質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

Q&A

解決済

2回答

9023閲覧

片方向リストを使ったクイックソートのプログラムについて質問があります

ccccididid

総合スコア23

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

0グッド

1クリップ

投稿2016/12/26 05:30

編集2016/12/26 06:34

C言語

1#include <stdio.h> 2 3struct node 4{ 5 int value; 6 struct node *next; 7}; 8 9static struct node * 10concatante (struct node *a, struct node *b) 11{ 12 struct node *p; 13 if (a == NULL) 14 return b; 15 else if (b == NULL) 16 return a; 17 for (p = a; p->next != NULL; p = p->next) 18 ; 19 p->next = b; 20 return a; 21} 22 23struct node * 24quick_sort_list (struct node *c) 25{ 26 int pivot; 27 struct node *t; 28 struct node *l_pivot = NULL; 29 struct node *e_pivot = NULL; 30 struct node *r_pivot = NULL; 31 32 if (c == NULL || c->next == NULL) 33 return c; 34 35 pivot = c->value; 36 37 for (; c != NULL; c = t) 38 { 39 t = c->next; 40 if (c->value < pivot) 41 { 42 c->next = l_pivot; 43 l_pivot = c; 44 } 45 else if (c->value == pivot) 46 { 47 c->next = e_pivot; 48 e_pivot = c; 49 } 50 else if (c->value > pivot) 51 { 52 c->next = r_pivot; 53 r_pivot = c; 54 } 55 } 56 57 l_pivot = quick_sort_list (l_pivot); 58 r_pivot = quick_sort_list (r_pivot); 59 60 return concatante (l_pivot, concatante (e_pivot, r_pivot)); 61} 62 63 64 65 66 #include <stdio.h> 67 #include <stdlib.h> 68 69struct node *quick_sort_list (struct node *); 70 71struct node 72{ 73 int value; 74 struct node *next; 75}; 76 77static void 78print_nodes (struct node *p) 79{ 80 for (; p != NULL; p = p->next) 81 printf (" %d", p->value); 82 printf ("\n"); 83} 84 85int 86main () 87{ 88 int list[] = { 1, 3, 7, 4, 2, 6, 5 }; 89 struct node *nodes = NULL; 90 int i; 91 92 for (i = sizeof list / sizeof list[0] - 1; i >= 0; --i) 93 { 94 struct node *p = malloc (sizeof *p); 95 if (p == NULL) 96 { 97 perror ("malloc"); 98 exit (EXIT_FAILURE); 99 } 100 p->value = list[i]; 101 p->next = nodes; 102 nodes = p; 103 } 104 105 print_nodes (nodes); 106 nodes = quick_sort_list (nodes); 107 print_nodes (nodes); 108 109 exit (EXIT_SUCCESS); 110} 111```以下のプログラムでわからないところがあります 112 113 114 115クイックソートの際、3つの条件で別々のリストに代入していますが 116各条件にある以下の部分の一行目の存在意義がいまいちわかりません 117 118c->next = l_pivot; 119l_pivot = c; 120 121わかる方教えてください

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2016/12/26 06:22

質問欄右上の<code>を押してでてくる'''の間にソースをコピペすると綺麗に表示できますよ。
ccccididid

2016/12/26 06:38

ありがとうございます 修正しました
guest

回答2

0

たとえば[6,5,2,3,1,4]というリストをソートするとして

5を処理するときに該当のif文の中に入ります。この時、cは5の入れ物を指すポインタ、l_pivotはnullなので、
5の入れ物の次はnullになり、l_pivotには5を指すポインタが入ります。

5->null

次に2を処理するときはcは2の入れ物を指すポインタ、l_pivotは5の入れ物を指すポインタが入っているので、
2の入れ物からは以下のように連結したリストが見えるようになります。

2->5->null

3に関しても同様です。
3->2->5->null

この時、3の次が2であることはl_pivotに2の入れものが入っていることから分かりますが、2の次が何であるかはc->next = l_pivotをして一つ前のl_pivotの入れ物のポインタを保存しておかないとわからないのです。そのためc->next = l_pivotをしているのです。

投稿2016/12/26 07:05

hitsujimeeee

総合スコア486

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

クイックソートアルゴリズムを復習せずに書いているので多少曖昧な部分は許してください。

クイックソートは、適当な値を中央値として、それより低い値のリスト、高い値のリストを仕訳していくことによって徐々に順序を整えていくアルゴリズムです。低い値のリストを作ったら、そのリストの中でまた同じように低い値のリスト、高い値のリストを作ります。これを、リストの仕訳ができなくなるところまで繰り返して最後に繋ぎ合わせます。
(それが if (c == NULL || c->next == NULL) return c;の部分です)

質問にあるc->next = l_pivot;というのは、低い値のリストを作成している部分になります。
片方向のリストなので低い値のリスト作成時には先頭に向かって値を追加していっています。

ちょっと分かりづらいので、各要素が全てpivotを下回りl_pivotに含まれる場合を図で説明します。
[0][1][2] と要素が並んでいた場合

・1回目の代入
l_pivotは最初はNULLです。
今現在持っている要素のc->NextにNULLを設定し、要素をl_pivotに設定します。
[0]->Next = NULL;
l_pivot = [0];
l_pivotから見た要素の並びは [0];

・2回目以降の代入
1つ前の要素を現在の要素のNextフィールドに設定し、要素をl_pivotに設定します。
[1]->Next = [0];
l_pivot = [1];
l_pivotから見た要素の並びは [1][0];

[2]->Next = [1];
l_pivot = [2];
l_pivotから見た要素の並びは [2][1][0];

となります。

クイックソートアルゴリズムでは、こうやって値をざっくり今の中央値より低い値、高い値により分け、それらを後に繋ぎなおすことでソートしていきます。

投稿2016/12/26 06:51

haru666

総合スコア1591

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問