qsort() は、C ライブラリに事前定義された標準関数です。この関数を使用して、配列を昇順または降順に並べ替えることができます。内部的にはクイックソートアルゴリズムを使用しているため、qsort という名前が付けられています。文字列や構造体を含むあらゆるデータ型の配列を並べ替えることができます。うまく機能し、実装が効率的です。 C++ には、C の qsort() に似た関数 sort() があります。実行時間、安全性、柔軟性などの点で、sort() は qsort() を上回ります。
このチュートリアルでは、関数 qsort() を例を挙げて説明します。 C 標準では関数の複雑さは指定されていませんでしたが、内部的にはクイック ソート アルゴリズムに従っているため、平均時間複雑さは暫定的に O(n*logn) と見なされます。関数は stdlib ヘッダー ファイルで定義されます。したがって、使用する前にそれを含める必要があります。
#include
関数の構文:
qsort(array, number, size, function)
配列 : ソートする配列。
番号 : 並べ替える配列内の要素の数
二分探索
サイズ : 配列の個々の要素のサイズ
関数 : 指定された形式で記述する必要があるカスタム比較関数:
関数の指定された形式:
int compare( const void* a, const void* b) { }
- qsort() は、配列内の 2 つの要素ごとに Compare() 関数を呼び出します。
- 引数 a と b は、比較する 2 つの要素を指す 2 つの void ポインターです。
- Compare() の本体は、次のように返されるように記述する必要があります。
- 2 つの要素が等しい場合は 0
- 最初の要素が 2 番目の要素より小さい場合は、-1 またはその他の負の整数
- 最初の要素が 2 番目の要素より大きい場合は、1 またはその他の正の数。
- 比較関数の名前は任意ですが、名前は qsort() 関数の引数として正確に指定する必要があります。
- const void* a は、a が値が固定の void ポインタであることを意味します。使用する前に、void ポインターを何らかのデータ型に型キャストする必要があります。
次に、さまざまなデータ型の配列を並べ替える関数を見ていきます。
1. 整数の並べ替え:
#include #include int compare(const void* num1, const void* num2) // comparing function { int a = *(int*) num1; int b = *(int*) num2; if(a > b) { return 1; } else if(a <b) { return -1; } 0; int main() arr[50], n, i; printf('enter the size of array to be sorted: '); scanf('%d', &n); printf(' enter elements into array: for(i="0;" i < n; i++) &arr[i]); qsort(arr, sizeof(int), compare); printf(' the sorted printf(' ['); if(i="=" n-1) prevent a comma(,) after last element printf('%d', arr[i]); break; printf('%d, ', printf(']'); pre> <p> <strong>Output:</strong> </p> <pre> Enter the size of the array to be sorted: 5 Enter elements into the array: 98 34 89 0 2 The sorted array: [0, 2, 34, 89, 98] </pre> <h3>Understanding:</h3> <p>In these two lines:</p> <p> <strong>int a = *(int*) num1;</strong> </p> <p> <strong>int b = *(int*) num2;</strong> </p> <p>The input array is of type . Hence, we must typecast the void pointers into integer pointers before performing any operations to allocate the required memory. We stored the values the two pointers are pointing at in two other integer variables, a and b. Then, we compared both values using the comparison operators.</p> <p>Instead of using two more temporary variables, we can write a one-line code:</p> <pre> int compare(const void* num1, const void* num2) { return *(int*)a - *(int*)b; } </pre> <ul> <li>If a==b, 0 is returned; if a > b, a positive integer is returned; if a <b, a negative integer is returned.< li> </b,></li></ul> <h3>2. Sorting strings</h3> <pre> #include #include #include int compare(const void* num1, const void* num2) { //char **a = (char**)num1; //char **b = (char**)num2; //return strcmp(*a, *b); return strcmp(*(char**)num1, *(char**)num2); } int main() { int n, i; char* arr[50]; printf('Enter the size of the array to be sorted: '); scanf('%d', &n); printf(' Enter elements into the array: '); for(i = 0; i <n; i++) { arr[i]="malloc(100*" sizeof(char)); scanf('%s', arr[i]); } qsort(arr, n, sizeof(char*), compare); printf(' the sorted array: '); printf(' ['); for(i="0;" i < n; if(i="=" n-1) printf('%s', break; printf('%s, ', printf(']'); pre> <p> <strong>Output:</strong> </p> <pre> Enter the size of the array to be sorted: 5 Enter elements into the array: hi hello how are you The sorted array: [are, hello, hi, how, you] </pre> <h3>Understanding:</h3> <ul> <li>We have an array of strings. The difference between an integer array and a string array is that: <ol class="points"> <li>An integer array is a collection of integers</li> <li>A string array is a collection of character arrays/character pointers.</li> </ol></li> <li>Hence, in the compare function, we need to typecast the void pointers to (char**)a and not (char*)a. <br> <strong>[[string 1], [string 2]?]</strong> <br> When we use char*, it points to the array, and then, to point to a string in the array, we need a double pointer.</li> <li>We used the strcmp() function here. The function is defined in the string.h header file. We need to include it first.</li> <tr><td>The function returns</td> : <ol class="points"> <li>0 if both strings are the same</li> <li>1 if the ASCII value of a character in the string is greater than the corresponding character in the second string</li> <li>-1 if the ASCII value of a character in the string is less than the corresponding character in the second string.</li> </ol> </tr></ul> <h3>3. Sorting an Array of Structure</h3> <pre> #include #include struct Structure { int num1; int num2; }s; typedef struct Structure data; int compare(const void* p, const void* q) { data *a = (data *)p; data *b = (data *)q; int first = (a -> num1)- (b -> num1); int second = (a -> num2)- (b -> num2); if(first == 0) { return second; } return first; } int main() { data array[5]; int i = 0; printf('Original array: '); printf('[['); for(i = 0; i <5; i++) { array[i].num1="rand()%10;" array[i].num2="rand()%10;" if(i="=" 4) printf('%d, %d]]', array[i].num1, array[i].num2); break; } %d], [', qsort(array, 5, sizeof(s), compare); printf(' sorted array: '); printf('[['); for(i="0;" i < 5; pre> <p> <strong>Output:</strong> </p> <pre> Original array: [[1, 7], [4, 0], [9, 4], [8, 8], [2, 4]] Sorted array: [[1, 7], [2, 4], [4, 0], [8, 8], [9, 4]] </pre> <h3>Understanding:</h3> <p>We declared an array of type Structure, meaning every element in the array is an array of structure elements. In the above program, the structure has two integer elements. The task is to sort the array with respect to the first Structure element, and if any two first elements are equal, we need to sort it using the second element.</p> <p> <strong>Example:</strong> </p> <p>[[1, 2], [3, 4], [1, 4]]</p> <p>Sorted array: [[1, 2], [1, 4], [3, 4]]</p> <p>We used the rand() function to generate random elements in the array. In the compare() function, we need to typecast the two pointers to type structure.</p> <img src="//techcodeview.com/img/c-tutorial/30/qsort-c.webp" alt="qsort() in C"> <p>The specialty of using qsort() is the custom compare function that we can design the way we want. We can also sort a few elements in an array and leave the rest unsorted.</p> <hr></5;></pre></n;></pre></b)>
理解:
これらの 2 行では次のようになります。
int a = *(int*) num1;
int b = *(int*) num2;
入力配列の型は です。したがって、必要なメモリを割り当てる操作を実行する前に、void ポインターを整数ポインターに型キャストする必要があります。 2 つのポインターが指す値を、他の 2 つの整数変数 a と b に保存しました。次に、比較演算子を使用して両方の値を比較しました。
さらに 2 つの一時変数を使用する代わりに、1 行のコードを書くことができます。
int compare(const void* num1, const void* num2) { return *(int*)a - *(int*)b; }
- a==b の場合、0 が返されます。 a > b の場合、正の整数が返されます。もし
2. 文字列のソート
#include #include #include int compare(const void* num1, const void* num2) { //char **a = (char**)num1; //char **b = (char**)num2; //return strcmp(*a, *b); return strcmp(*(char**)num1, *(char**)num2); } int main() { int n, i; char* arr[50]; printf('Enter the size of the array to be sorted: '); scanf('%d', &n); printf(' Enter elements into the array: '); for(i = 0; i <n; i++) { arr[i]="malloc(100*" sizeof(char)); scanf(\'%s\', arr[i]); } qsort(arr, n, sizeof(char*), compare); printf(\' the sorted array: \'); printf(\' [\'); for(i="0;" i < n; if(i="=" n-1) printf(\'%s\', break; printf(\'%s, \', printf(\']\'); pre> <p> <strong>Output:</strong> </p> <pre> Enter the size of the array to be sorted: 5 Enter elements into the array: hi hello how are you The sorted array: [are, hello, hi, how, you] </pre> <h3>Understanding:</h3> <ul> <li>We have an array of strings. The difference between an integer array and a string array is that: <ol class="points"> <li>An integer array is a collection of integers</li> <li>A string array is a collection of character arrays/character pointers.</li> </ol></li> <li>Hence, in the compare function, we need to typecast the void pointers to (char**)a and not (char*)a. <br> <strong>[[string 1], [string 2]?]</strong> <br> When we use char*, it points to the array, and then, to point to a string in the array, we need a double pointer.</li> <li>We used the strcmp() function here. The function is defined in the string.h header file. We need to include it first.</li> <tr><td>The function returns</td> : <ol class="points"> <li>0 if both strings are the same</li> <li>1 if the ASCII value of a character in the string is greater than the corresponding character in the second string</li> <li>-1 if the ASCII value of a character in the string is less than the corresponding character in the second string.</li> </ol> </tr></ul> <h3>3. Sorting an Array of Structure</h3> <pre> #include #include struct Structure { int num1; int num2; }s; typedef struct Structure data; int compare(const void* p, const void* q) { data *a = (data *)p; data *b = (data *)q; int first = (a -> num1)- (b -> num1); int second = (a -> num2)- (b -> num2); if(first == 0) { return second; } return first; } int main() { data array[5]; int i = 0; printf('Original array: '); printf('[['); for(i = 0; i <5; i++) { array[i].num1="rand()%10;" array[i].num2="rand()%10;" if(i="=" 4) printf(\'%d, %d]]\', array[i].num1, array[i].num2); break; } %d], [\', qsort(array, 5, sizeof(s), compare); printf(\' sorted array: \'); printf(\'[[\'); for(i="0;" i < 5; pre> <p> <strong>Output:</strong> </p> <pre> Original array: [[1, 7], [4, 0], [9, 4], [8, 8], [2, 4]] Sorted array: [[1, 7], [2, 4], [4, 0], [8, 8], [9, 4]] </pre> <h3>Understanding:</h3> <p>We declared an array of type Structure, meaning every element in the array is an array of structure elements. In the above program, the structure has two integer elements. The task is to sort the array with respect to the first Structure element, and if any two first elements are equal, we need to sort it using the second element.</p> <p> <strong>Example:</strong> </p> <p>[[1, 2], [3, 4], [1, 4]]</p> <p>Sorted array: [[1, 2], [1, 4], [3, 4]]</p> <p>We used the rand() function to generate random elements in the array. In the compare() function, we need to typecast the two pointers to type structure.</p> <img src="//techcodeview.com/img/c-tutorial/30/qsort-c.webp" alt="qsort() in C"> <p>The specialty of using qsort() is the custom compare function that we can design the way we want. We can also sort a few elements in an array and leave the rest unsorted.</p> <hr></5;></pre></n;>
理解:
- 文字列の配列があります。整数配列と文字列配列の違いは次のとおりです。
- 整数配列は整数のコレクションです
- 文字列配列は、文字配列/文字ポインターのコレクションです。
- したがって、compare 関数では、void ポインターを (char*)a ではなく (char**)a に型キャストする必要があります。
[[文字列 1]、[文字列 2]?]
char* を使用する場合、それは配列を指しますが、配列内の文字列を指すにはダブル ポインターが必要です。 - ここでは strcmp() 関数を使用しました。この関数は、string.h ヘッダー ファイルで定義されます。まずそれを含める必要があります。
- 両方の文字列が同じ場合は 0
- 文字列内の文字の ASCII 値が 2 番目の文字列内の対応する文字より大きい場合は 1
- 文字列内の文字の ASCII 値が 2 番目の文字列内の対応する文字より小さい場合は -1。
3. 構造体の配列のソート
#include #include struct Structure { int num1; int num2; }s; typedef struct Structure data; int compare(const void* p, const void* q) { data *a = (data *)p; data *b = (data *)q; int first = (a -> num1)- (b -> num1); int second = (a -> num2)- (b -> num2); if(first == 0) { return second; } return first; } int main() { data array[5]; int i = 0; printf('Original array: '); printf('[['); for(i = 0; i <5; i++) { array[i].num1="rand()%10;" array[i].num2="rand()%10;" if(i="=" 4) printf(\'%d, %d]]\', array[i].num1, array[i].num2); break; } %d], [\', qsort(array, 5, sizeof(s), compare); printf(\' sorted array: \'); printf(\'[[\'); for(i="0;" i < 5; pre> <p> <strong>Output:</strong> </p> <pre> Original array: [[1, 7], [4, 0], [9, 4], [8, 8], [2, 4]] Sorted array: [[1, 7], [2, 4], [4, 0], [8, 8], [9, 4]] </pre> <h3>Understanding:</h3> <p>We declared an array of type Structure, meaning every element in the array is an array of structure elements. In the above program, the structure has two integer elements. The task is to sort the array with respect to the first Structure element, and if any two first elements are equal, we need to sort it using the second element.</p> <p> <strong>Example:</strong> </p> <p>[[1, 2], [3, 4], [1, 4]]</p> <p>Sorted array: [[1, 2], [1, 4], [3, 4]]</p> <p>We used the rand() function to generate random elements in the array. In the compare() function, we need to typecast the two pointers to type structure.</p> <img src="//techcodeview.com/img/c-tutorial/30/qsort-c.webp" alt="qsort() in C"> <p>The specialty of using qsort() is the custom compare function that we can design the way we want. We can also sort a few elements in an array and leave the rest unsorted.</p> <hr></5;>
理解:
Structure 型の配列を宣言しました。これは、配列内のすべての要素が構造体要素の配列であることを意味します。上記のプログラムでは、構造体に 2 つの整数要素があります。タスクは、最初の Structure 要素に関して配列を並べ替えることです。最初の 2 つの要素が等しい場合は、2 番目の要素を使用して並べ替える必要があります。
例:
[[1, 2]、[3, 4]、[1, 4]]
ソートされた配列: [[1, 2], [1, 4], [3, 4]]
rand() 関数を使用して、配列内にランダムな要素を生成しました。 Compare() 関数では、2 つのポインターを型構造体に型キャストする必要があります。
qsort() の使用の特徴は、希望どおりに設計できるカスタム比較関数です。配列内のいくつかの要素をソートし、残りをソートしないままにすることもできます。
5;>