C言語の詳細なバブルソート
1.基本的な考え方
バブルソートは、最も簡単で古典的な交換ソートです。基本的な考え方は、隣接する2つの要素のサイズを左から右に比較することです。左側が右側よりも大きい場合は、交換します。ソート後、次のように作成できます。最大値は右端に浮かんでいます。この操作を繰り返して、配列を順番に保ちます。
2.アルゴリズムの実装と最適化
バブルソートを実現するために、まずバブルソートを作成します。非常に簡単です。左から右に比較できます。左が右よりも大きい限り、交換が行われます。
注:
配列には、最初の要素を開始した配列のn個の要素があり、最初のn-1個の要素の配列の終わりをn-1回比較しました。たとえば、次の図では、最初から6番目の終わりまでです。ソートコードは1回の旅行で書くことができます:
//1.第1趟排序,从第1个元素开始到n-1个元素结束,比较n-1次
for (int j = 0; j < n-1; ++j)
{
//如果左边大于右边,则交换位置
if (a[j] > a[j + 1])
{
Swap(&a[j], &a[j + 1]);
}
}
このように並べ替えた後、最大数を右端にポップできます。この操作をn-1回繰り返すと、次に大きい数と次に大きい数を右端にポップして、ループを完了できます。
void BubbleSort1(int* a, int n)
{
//排n趟就可以让数组有序
int end=n-1;
while(end>0)
{
//一趟排序,从第一个元素开始到n-1个元素结束,
for(int j = 0; j<n-1; ++j)
{
//如果左边大于右边,就交换
if(a[j]>a[j+1])
{
Swap(&a[j],&a[j+1]);
}
}
--end;
PrintArr(a,n);
}
}
このコードは順に配列を作ることができるが、それは、冗長なソートを有する配列で最大の要素は、ソートの一回の通過後に決定することができるので、次の最大の要素の位置はまた、ソートの第二の通過後に決定されるので、最適化されたコードを続行できます
図に示すように、最初のパスは1つの要素からn-1回開始し、56は右端に移動します
。2番目のパスでは、最後の要素の位置が決定され、n-2のみを比較します。回数、55は右から2番目に進みます;
……
6番目のパスは、配列を順番に作成するために1回だけ比較する必要があります。
配列にn個の要素があるとすると、n-1回配置する必要があり、各パスはiで表されます。i番目のパスはni-1回、コードを比較する必要があります。
void BubbleSort2(int* a, int n)
{
//n-1趟排序
for(int i = 0; i < n-1; ++i)
{
//每一趟比较n-i-1次
for(int j=0; j<n-i-1; ++j)
{
if(a[j]>a[j+1])
{
Swap(&a[j],&a[j+1]);
}
}
PrintArr(a,n);
}
}
このアルゴリズムは引き続き最適化できます。配列がi番目の並べ替え後に既に順序付けられていると仮定すると、後で比較しないでください。この最適化は簡単です。フラグを定義するだけで済みます。1回の並べ替えパスでフラグが変更されない場合、この配列はすでに正常であると考えて、ループを終了します。
void BubbleSort(int* a, int n)
{
//n-1趟排序
for(int i = 0; i < n-1; ++i)
{
int flag = 0; //设置flag
//每一趟比较n-i-1次
for(int j=0; j<n-i-1; ++j)
{
if(a[j]>a[j+1])
{
flag = 1; //如果该趟排序发生交换,flag置1
Swap(&a[j],&a[j+1]);
}
}
PrintArr(a,n);
//一趟排序过后没有发生变化,说明数组已经有序
if(flag == 0)
break;
}
}
三、コードリスト
#include <stdio.h>
void PrintArr(int* a, int n)
{
for(int i = 0; i < n; ++i)
{
printf("%d ",a[i]);
}
printf("\n");
}
void Swap(int* px, int* py)
{
int tmp = *px;
*px = *py;
*py = tmp;
}
void BubbleSort1(int* a, int n)
{
//排n趟就可以让数组有序
int end=n-1;
while(end>0)
{
//一趟排序,从第一个元素开始到n-1个元素结束,
for(int j = 0; j<n-1; ++j)
{
//如果左边大于右边,就交换
if(a[j]>a[j+1])
{
Swap(&a[j],&a[j+1]);
}
}
--end;
PrintArr(a,n);
}
}
void BubbleSort2(int* a, int n)
{
//n-1趟排序
for(int i = 0; i < n-1; ++i)
{
//每一趟比较n-i-1次
for(int j=0; j<n-i-1; ++j)
{
if(a[j]>a[j+1])
{
Swap(&a[j],&a[j+1]);
}
}
PrintArr(a,n);
}
}
void BubbleSort(int* a, int n)
{
//n-1趟排序
for(int i = 0; i < n-1; ++i)
{
int flag = 0; //设置flag
//每一趟比较n-i-1次
for(int j=0; j<n-i-1; ++j)
{
if(a[j]>a[j+1])
{
flag = 1; //如果该趟排序发生交换,flag置1
Swap(&a[j],&a[j+1]);
}
}
PrintArr(a,n);
//一趟排序过后没有发生变化,说明数组已经有序
if(flag == 0)
break;
}
}
int main()
{
int a[] = {
25,6,56,24,9,12,55};
int b[] = {
25,6,56,24,9,12,55};
int c[] = {
25,6,56,24,9,12,55};
int n = sizeof(a)/sizeof(a[0]);
printf("-----BubbleSort------\n");
BubbleSort(a,n);
printf("-----BubbleSort1------\n");
BubbleSort1(b,n);
printf("-----BubbleSort2------\n");
BubbleSort2(c,n);
//PrintArr(a,n);
return 0;
}