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

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

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

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

Q&A

解決済

1回答

2072閲覧

C言語 クイックソートの文法の意図が分からない

GIOGIO

総合スコア23

C

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

0グッド

0クリップ

投稿2020/04/05 07:43

C

1#include <stdio.h> 2#define SIZE 6 3 4 5void quick_sort(int[], int, int); 6 7int main() 8{ 9 int array[SIZE] = {3, 2, 6, 1, 5, 4}; 10 int i; 11 12 printf("Before sort: "); 13 for (i = 0; i < SIZE; i++) { 14 printf("%d ", array[i]); 15 } 16 printf("\n"); 17 18 quick_sort(array, 0, 5); 19 20 printf("After sort: "); 21 for (i = 0; i < SIZE; i++) { 22 printf("%d ", array[i]); 23 } 24 printf("\n"); 25 return 0; 26} 27 28//値を入れ替える関数 29void swap(int *x, int *y) { 30 int temp; 31 temp = *x; 32 *x = *y; 33 *y = temp; 34} 35 36/*** 37 * pivotを決め、 38 * 全データをpivotを境目に振り分け、 39 * pivotの添え字を返す 40 ***/ 41int partition(int array[], int left, int right) { 42 int i, j, pivot; 43 44 i = left; 45 j = right + 1; 46 //先頭要素をpivotとする 47 pivot = left; 48 49 do { 50 do {i++; } while (array[pivot] > array[i]); 51 do {j--; } while (array[pivot] < array[j]); 52 //pivotより小さいものを左へ、大きいものを右へ 53 if (i < j) { 54 swap(&array[i], &array[j]); 55 } 56 } while (i < j); 57 swap(&array[pivot], &array[j]); 58 //pivotを更新 59 return j; 60} 61 62////クイックソート 63void quick_sort(int array[], int left, int right) { 64 int pivot; 65 if (left < right) { 66 pivot = partition(array, left, right); 67 quick_sort(array, left, pivot-1); 68 //pivotを境に再帰的にクイックソート 69 quick_sort(array, pivot+1, right); 70 } 71} 72

C

1実行結果: Before sort: 3 2 6 1 5 4 2 After sort: 1 2 3 4 5 6

クイックソート関数の
if (left < right) という部分の意図がわかりません。
なぜ、このような条件をつけているのでしょうか?なくてもいいような気がします。

クイックソート関数の
quick_sort(array, left, pivot-1);
quick_sort(array, pivot+1, right);
なぜ2回も再帰を行なっているのでしょうか?
それと、引数が2つとも違うのはなぜなんでしょうか?

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

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

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

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

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

Zuishin

2020/04/05 07:46

前半と後半をソートすればすべてソートできるというのがクイックソートのアルゴリズムの基本です。 だから半分に分けて二回ソートします。 left < right は継続条件です。 left >= right になったら終了です。
guest

回答1

0

ベストアンサー

クイックソートは、言語ではなくて、アルゴリズムですから、文法というのは変です。

int array[SIZE] = {3, 2, 6, 1, 5, 4}; の状態で
quick_sort(array, 0, 5) を呼び出します。

left = 0, right = 5 です。left < right ですから、
pivot = partition(array, left, right) を呼び出します。
戻ってきたとき、
array = { 2, 1, 3, 6, 5, 4 }, pivot = 2 になっています。
array[pivot] = array[2] = 3 で、
{ 2, 1 } は 3 より小さい。{ 6, 5, 4 } は 3 より大きい。

{ 2, 1 } をソートするため quick_sort(array, left, pivot-1) を呼び出し
{ 6, 5, 4 } をソートするため quick_sort(array, pivot+1, right) を呼び出します。
これが 2回も再帰を行ない、引数が2つとも違う理由です。

これを繰り返すと、ソートする部分の長さがだんだん小さくなって 0 か 1 になります。

left < right だとソートする array の要素が 2個以上あるのでソートが必要ですが、
そうでないとソートする必要がありません。
そのため if (left < right) という条件が付いているのです。

投稿2020/04/05 08:33

kazuma-s

総合スコア8224

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

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

GIOGIO

2020/04/05 10:26

ありがとうございます。ようやく理解できました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問