• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C言語のリストのソートについて質問します。)

C言語のリストのソートについて質問します

このQ&Aのポイント
  • C言語のリストのソートについて質問します
  • リストのソートアルゴリズムは機能しているが、複数回実行する必要があります。一度で完全にソートする方法を知りたいです。
  • 降順のソートも同様に問題があります。アドバイスをいただけますか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.7

まずリストの操作では中のデータを操作してはいけません。この場合は単純ですが実際には構造が不明な場合が多いのです。ポインタを繋ぎかえるのが基本的です。 バブルソートは極めて簡単で単純に隣同士を入れ替えるだけです。 struct ans root; struct ans *back,*temp,*last; root.next=head; last=NULL; とすると内側のループは以下のように記述できます。(携帯からなのでコンパイルしていません) for(back=&root;(head=(temp=head->next))!=last;back=temp)  if(head->data<temp->data){   temp->next=head->next;   back->next=head;   head->next=temp;  } これを交換する最後のデータがリスト先頭に達するまで繰り返すだけです。 for(last=NULL;(head=root.next)!=last;last=temp) ・・・ return root.next; バブルソートはデータが多いと直ぐ破綻しますが、とりあえず動くようにしてみてください。 動いたらバブルソートの改良、双方向リンク・リストに書き換えみる事です。 バブルソートは昇順に並べる場合には、交換が発生したときに最小値がどうか調べて、最小値を先頭に移動する事で実行時間の短縮ができます。また一度も交換が発生しなければ打ち切ります。 データが数万個以上でも実用的なソートもありますが、それはリンクの操作をマスターしてからですね。

aida13
質問者

お礼

ありがとうございます。やはり双方向リストを使わなければ無理なようですね。勉強して再チャレンジしてみたいと思います。

すると、全ての回答が全文表示されます。

その他の回答 (8)

回答No.9

#7です。ミスがありました。 for(back=&root;(head=(temp=head->next))!=last;back=temp) はfor(back=&root;(head=(temp=head)->next)!=last;back=temp) です。(-o-;)

すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.8

>挿入そのものは 2/n でも、 これを「2ぶんのエヌ」と読ませるのは至難の業です。 どう見ても「エヌぶんの2」としか読めません。

すると、全ての回答が全文表示されます。
回答No.6

済みません、訂正です。 挿入そのものは 2/n でも、それを n個分繰り返すから、全体のオーダーとしては n^2 ですね。 最近ぼけてます。

すると、全ての回答が全文表示されます。
回答No.5

挿入時にソートなら、挿入の前後でソートができているというのが仮定できるはずなので(少なくとも、挿入した後はソート済み……だから、ひとつ以上挿入したらその時点ではソート完了)処理オーダーはリストでも n / 2 の気がする。 先頭から確認して、大きい/小さい要素に突き当たったらそこに挿入……でいいのかな?

すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.4

>「データを挿入するときにソート」したら n個のデータに対して n^2 時間かかるけど, >「データの挿入だけしておいてあとでソート」したら n log n 時間ですむから速いよね>#1. まあ、5件くらいのデータだからいいじゃないですか。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

「データを挿入するときにソート」したら n個のデータに対して n^2 時間かかるけど, 「データの挿入だけしておいてあとでソート」したら n log n 時間ですむから速いよね>#1. さておき, このプログラムじゃダメダメですよ. sort_up でやってることって, しょせん「バブルソートの 1パス分」だけだもの. 手を動かして紙の上で実際にやってみましたか? あと, sort_up の second_head = (struct ans *)malloc(sizeof(struct ans)); って何の意味があるの? その直後で second_head に代入してるから, これは結局システムを圧迫するためだけだよね? ソートアルゴリズムなんかいっくらでもあるから, そのうち「リストに適切」なものをちゃんと調べて実装すればいいんだけどなぁ.

すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.2

>両端にNULLを置いてしまったらsort_up関数内の >   if( head->next == NULL )に引っかかってしまいそうな気もする 何をおっしゃっているのか、さっぱりわかりません。 双方向リストといってもいろんな考え方がありますが、 よくありそうなのは下記のとおりです。どこにも矛盾はないはずです。 先頭データ(仮に左端とします)のnextポインタ:左から2番目のデータを指す 先頭データのprevポインタ:NULL(先頭の左側にはデータがない) 最後尾(右端)データのnextポインタ:NULL(最後尾の右側にはデータがない) 最後尾データのprevポインタ:右から2番目のデータを指す

すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.1

そもそも、リスト構造は、構築した「後で」ソートするには あまり向いていないデータ構造です。 データをリストに「挿入する」ときにソートするようにすれば、 すべてのデータを挿入した時点でソート済みのリストができあがっています。 逆順のソートがしたければ、双方向リストを作ればよいでしょう。

aida13
質問者

お礼

なるほど!確かに前のdataも見れるならうまくいきそうです。その場合前を見る(struct ans *prev)とするなら、(struct ans *next)をsort_up関数内で使った式でそのまま流用しても大丈夫でしょうか?

aida13
質問者

補足

考え方はわかりましたが、自分は双方向リストを使ったことがないので何とも…。両端にNULLを置いてしまったらsort_up関数内の      if( head->next == NULL )に引っかかってしまいそうな気もするんですが…

すると、全ての回答が全文表示されます。
筆まめver32の機能制限について
このQ&Aのポイント
  • 筆まめVER32を使用している方が次の年賀状を作成しようとした際に、トップメニューの内「年賀状作成」以下のほとんどの機能が制限されて使用できない問題が発生しています。
  • 制限を解除する方法についてご質問です。
  • また、OSはWindows10を使用しています。
回答を見る

専門家に質問してみよう