こんにちは, 今日私たちが共有するのは、バブル関数を使用して qsort を実装するということです。これはクイック ソートです。以前にもライブラリ関数 qsort の使用方法についても話しました。今日は、バブル関数を使用してそれを実装してみます。もちろん、 、qsort も確認しましたが、今後も確認します。今後も改善していきます。最近、私は防御が壊れている大学生です、悲しいことに!
まず、qsort がどのようなものかを見てみましょう。Web サイト cplusplus にログインできます。
この Web サイトを通じて、qsor の使用方法を確認できます。まず、戻り値の型が void で、パラメータが次のとおりであることがわかります。 Base、num、size、Compar 英語でわかることは、base が実際に並べ替えたいものであるということです。前の例では void* ポインターが使用されていました。void はゴミ箱と考えることができます。何でも受け取ることができます
。 array は構造体にすることもできるため、ここでの void* は、このポインターが指す型が int、構造体、または double 型のいずれでもよいことを示します。
それでは、まずバブル関数がどのようなものかを書いていきますが、前回の記事を読んでいただいた方はご存知かと思いますが、手作りバブルソートです。
void bubble(int* arr, int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; i < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = arr[j];
}
}
}
}
バブリング プログラムを見てみましょう。最初のループは並べ替えの回数を決定します。たとえば、要素が 10 個ある場合、それらを 10 回並べ替える必要がありますか?実際には 9 回で十分です。最後のループはすでに並べ替えられています, それで、ソートする必要はないので、必要なのは 9 回だけです。昇順であると仮定しているため、つまり、前の値が次の値よりも大きいです。したがって、最初のパスでは、最大の数値が最後にあるため、後でループするときに i を減算する必要があります。バブルソートは誰にとっても非常に簡単でなければなりません。
それでは、qsort の実装をシミュレートするときにバブル ソートをどうすればよいでしょうか? まず、qsort のパラメーターを使用できます。
次に、このように書くことができますvoid bubble(void* base, int num, int sz, int (*cmp)(const void*, const void*))
。したがって、その後に行う必要があることは、実際にはバブルソートのアイデアと同じであり、最初のループの回数であるため、次のコードが表示されます。
void bubble(void* base, int num, int sz, int (*cmp)(const void*, const void*))
{
int i = 0;
for (i = 0; i < num - 1; i++)
{
int j = 0;
for (j = 0; j < num - 1 - i; j++)
{
if (cmp((char*)base + j * sz, (char*)base + (j + 1) * sz) > 0)
{
swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);
}
}
}
}
ここにすべて公開しましたので、説明しやすくなります。まず、関数を使用して、0 より大きいかどうかを判断します。関数の実装方法は次のとおりです。ここで渡されるパラメーターは、特に重要な場所です。なぜ、コードに到達したら、最初にそれを char* 型にキャストする必要があります。これにより、その後のアクセスが容易になります。まず、比較関数を見てみましょう。
int cmp(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
比較しているのは整数型なので、最初に整数型にキャストする必要があります。その後、逆参照操作にアクセスできるようになります。また、ポインタを受け取るために void 型を使用するため、ここにも利点があります。つまり、double などの任意のタイプのデータを比較できます。タイプ、変更する必要があるのは、それを double タイプに変換することであり、構造もソートできます。これは、素早いソートを満たしており、多くのデータをソートできます。データ?
次に、スワップ関数を再度改善しましょう。コードを見ると、渡したパラメータが実際には同じであることがわかります。なぜこれでしょうか。それは、データのタイプがわからないからです。したがって、このタイプのデータを知る必要があります。ここにデータを 1 つずつ入力します。サイズ、すべて sz パラメータを渡す必要があるので、交換関数のコードを見てみましょう
void swap(char* e1, char* e2,int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
char tmp = *e1;
*e1 = *e2;
*e2 = tmp;
e1++;
e2++;
}
}
ここで誤解があります。私も最初に作りました。間違えないでください。まずポインタを渡して char 型を書きます。受け取ったのは char* のようなポインタです。そして、交換されるのはポインタはアドレスなので、アドレスではありません。これはわかっているので、ここではポインタが指す文字を交換しています。1 つずつ交換しているので、全員が交換できるように外部にループを設定する必要があります。パラメータ sz も渡す必要がある理由は次のとおりです。完全なコードは次のとおりです。
#include<stdio.h>
void print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int cmp(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void swap(char* e1, char* e2,int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
char tmp = *e1;
*e1 = *e2;
*e2 = tmp;
e1++;
e2++;
}
}
void bubble(void* base, int num, int sz, int (*cmp)(const void*, const void*))
{
int i = 0;
for (i = 0; i < num - 1; i++)
{
int j = 0;
for (j = 0; j < num - 1 - i; j++)
{
if (cmp((char*)base + j * sz, (char*)base + (j + 1) * sz) > 0)
{
swap((char*)base + j * sz, (char*)base + (j + 1) * sz, sz);
}
}
}
}
int main()
{
int arr[] = {
9,8,0,5,5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
print(arr,sz);
bubble(arr, sz, sizeof(arr[0]), cmp);
print(arr,sz);
return 0;
}
qsort 関数のバブリング バージョンもここで正常に実装されています。ここでは効率については話しません。重要なのは、この考え方を知ることです。後で 8 つの主要な並べ替えを学習するときに、クイック ソートについても学習します。方法は 3 つあります。急いで実装する必要はありません。
今日は学校で書いた 2 回目の記事です。昨日コンピューターが壊れたので、システムを再インストールしなければなりません。最近、物事がうまくいかないことがよくあります。物事がうまくいかないときは、とても悲しいです。また、メンタルを調整できることを願っていますこの数日間、皆さんありがとうございました。後で共有しますので、一緒に進歩しましょう! !!