回答編集履歴

1

回答がまったくの見当違いだったため、ご指摘をしてくださった方々の意見も取り入れた回答としての修正を行う

2022/06/08 05:57

投稿

BeatStar
BeatStar

スコア4958

test CHANGED
@@ -1,26 +1,30 @@
1
- バブルソート等を用いてソートしたいってことですよね?
1
+ ~~バブルソート等を用いてソートしたいってことですよね?かなり厳しいかと。一応できなくはないですが、リスト構造の良さを捨ててしまっていますよそれ。そもそも配列構造(C++でいえばstd::vectorも含む)とリスト構造の違いを理解していればありえないと思うのですが…細かい説明は省きますが、配列構造はその名の通り、配列です。なのでランダムアクセスは得意ですが、最後尾や先端とかに新しくデータを追加したり削除したりとかが苦手です。どうしても一時的に別の配列を用意してそこにコピーして削除するものは削除し、追加するなら追加する…という処理を加えてすげ替える。でもリスト構造はあの有名なイメージ(基本情報技術者試験ですら出てくる)なので、ランダムアクセスは苦手だけど、最後尾や先端とかに追加したり削除したりとかは得意。バブルソートはarr[1]とかみたいなランダムアクセスをしながら行いますよね。(多分やり方次第ではランダムアクセスしなくてもできるとは思うが、無学な俺には無理…)ということはリスト構造とは相性が悪すぎる。ランダムアクセスが苦手なものを使うわけだから。どうしてもバブルソートで行うなら、「**リストからデータを取り出して、一旦配列にコピー。その配列をバブルソートで整列させて、元のリストに戻す。**」と言う作業をしないといけません。無駄が多すぎます。リスト構造の良さを切り捨てていますね。それならいっそ、最初から配列構造で管理したほうがいいです。リスト構造でソート済みで管理したいだけなら、「**追加時に、ソート済みになるように位置を調べてそこに追加する**」でしょうか。この考え方はあるサイトさんから学んだのですが、追加時にリニアサーチで「ソート済みになるように追加位置を決める」。その後にそこに追加する。って言う感じでした。まず an = { 1, 3, 8 } に 5 を追加したい場合、まずanにあるデータ列を見て 5 をどこに追加すればソート済みになるか調べる。3 と 8 の間、つまり(0番目から考えると) 2番目に追加すればソート済みになりそうですね。ということで、この2番目に5を追加すればいい。ってことです。これを追加するときに行う。一応リスト構造は走査するためのポインタ(C++でいうiterator)がその位置にあって、行ったり来たりすることを考慮しないのならO(1)です。つまりどこに挿入しようと常に一定の時間しかかからないです。データ量がどんなに大きくとも。(ただし「どこに挿入するか」とかのチェックは考慮していない)~~
2
2
 
3
- かなり厳しいかと。
3
+ ----
4
- 一応できなくはないですが、リスト構造の良さを捨ててしまっていますよそれ。
5
4
 
6
- そもそも配列構造(C++でいえばstd::vectorも含む)とリスト構造の違いを理解していればありえないと思うのですが…
5
+ [修正]
7
6
 
8
- 細かい説明は省きすが、配列構造はその名の通り、配列ですでランダムアクセス得意ですが、最後尾や先端とかに新くデータを追加しり削除したりとかが苦手です。どうしても一時的に別の配列を用意してそこにコピーして削除するものは削除し、追加するなら追加するという処理を加えてすげ替える。
7
+ すみせん修正前回答間違えていました…
8
+ 私の知識不足が原因でした…
9
9
 
10
- でもリスト構造はあの有名なイメージ(基本情報技術者試験ですら出てくる)なで、ランダムアクセスは苦手だけど、最後尾や先端とかに追加した削除したりとかは得意
10
+ ご指摘を受けよく考えと、バブルソート要件には「ランダムアクセスで行う事」ませんでした
11
11
 
12
- バブルソートはarr[1]とかみたいなランダムアクセスをしながら行いますよね。(多分やり方次第ではランダムアクセスしなくてもできるとは思うが、無学な俺には無理…)
12
+ ----------------
13
13
 
14
- ということはリスト構造とは相性が悪ぎる
14
+ そのままやればいいかす。
15
- ランダムアクセスが苦手なものを使うわけだから。どうしてもバブルソートで行うなら、「**リストからデータを取り出して、一旦配列にコピー。その配列をバブルソートで整列させて、元のリストに戻す。**」と言う作業をしないといけません。
16
15
 
17
- 無駄多すぎます。リスト構造の良を切り捨すね。それならいっそ、最初から配列構造
16
+ majiponiさんご指摘してくだったように、**先端から比較し交換すればい**ですね。
18
- で管理したほうがいいです。
19
17
 
18
+ たとえば an = { 3, 2, 6, 1 } であれば、まず先端である 3 のところにポインタを設定し、
19
+ その次の値と比較。 ポインタを pとし、条件式を``p->num > p->num + 1``とすると 3 > 2 となり、条件を満たしますから、
20
+ さらに別の、格納されているデータの型、つまり上記の場合はint型の変数またはポインタを用いて入れ替える。
20
- リスト構造でソート済みで管理したいだけら、「**追加時に、ソート済みになように位置調べそこ追加する**」でしょうか
21
+ そうすると an = { 2, 3, 6, 1 } となる。ポインタずらし( p + 1 )、3 と 6 も同様にする。
22
+ …とやると、an = { 2, 3, 1, 6 } となるはずです。これで最大値 6 が確定。
21
- 方はあるサイトさんから学んだのですが、追加時リニアサーチで「ソート済みになるように追加位置を決める」。その後にそこに追加って言う感じでした。
23
+ また先端に戻って 2 と 3を比較。3と1を比較…とやり、要素数分-1した回数行ば結果的にソートされま
24
+ (後から考えてやっとわかった…)
22
25
 
23
- まず an = { 1, 3, 8 } に 5 を追加したい場合まずanにあるデー見て 5 をどこに追加ればソート済みになか調べる。3 と 8 間、つまり(0番目から考えると) 2番目に追加すればソート済みになりそうですね。ということで、この2番目に5追加すればい。っことです。
26
+ あるいはdodox86さんがご指摘てくださっように**ポインタを格納するため配列いて行う**方法もありま
27
+ (流石にこれはまったく気づかなかった…)
24
28
 
25
- これを追加するときに行う。一応リスト構造は走査するためのポインタ(C++でいうiterator)がその位置にあって、行ったり来たりすることを考慮しないのならO(1)です。つまりどこに挿入しようと常に一定の時間しかかからないです。データ量がどんなに大きくとも。(ただし「どこに挿入するか」とかのチェックは考慮していない)
26
29
 
30
+