冒泡排序(Bubble Sort):一次比较两个元素,如果他们的顺序错误就把他们交换过来,重复道数列已经不用再交换。冒泡排序名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。相当于升序操作。
每一趟冒泡排序,就排序一个数,可以形象地认为把一个大的数字放到水底,把小的数放在水面,慢慢冒出泡泡来。
void bubble_sort(int* arr, int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{//sz-1是冒泡排序的趟数
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{//sz-1-i是每一趟冒泡排序要比较的元素个数
if (arr[j] > arr[j + 1])//升序排序
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[] = { 5,9,8,2,1,4,7,6,3 };
//对arr进行排序,排成升序
//arr是数组,对arr进行传参,实际上传递的是
//arr的首元素的地址
//所以不能在自定义函数内部进行定义
int sz = sizeof(arr) / sizeof(arr[0]);//10
buuble_sort(arr,sz);//冒泡排序函数
//此时将已经算好的sz传过去
int i = 0;
for (i=0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
看懂上面的代码后,会发现假如一个数组已经是有序数组,它仍然一个个重复地进行比较,降低了排序效率,下面来改进这段代码。
void buuble_sort(int arr[], int sz)//传过来的是&arr[0],即int*arr,值为4,导致下面求出的值为1;
{
//int sz = sizeof(arr) / sizeof(arr[0]);//这里返回值为1;是因为主函数传数组arr过来的时候,传的是首元素的地址
//
// 所以不能在这里计算sz
//确定冒泡排序的趟数
int i = 0;
for (i = 0; i < sz; i++)
{
int j = 0;
int flag = 1;//假设这一趟冒泡排序已经有序,就让flag=1;
//这里的flag不能放在第一个for循环外部,因为每次第二个for循环结束后,如果无序,flag变成0,回到第一个for循环之后,要重新 flag =1;
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
flag = 0;//如果没完全有序,则flag=0,我们才能知道是否完全有序
}
}
if (flag == 1)
{
break;//此时已经完全有序,直接跳出循环,后续就不用再比较了
//本来if语句中不能用break,但是break是为了跳出循环,这里的if是放在for循环里面,故可以用break;
}
}
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1 };
//对arr进行排序,排成升序
//arr是数组,对arr进行传参,实际上传递的是
//arr的首元素的地址
//所以不能在自定义函数内部进行定义
int sz = sizeof(arr) / sizeof(arr[0]);//10
buuble_sort(arr,sz);//冒泡排序函数
//此时将已经算好的sz传过去
int i = 0;
for (i=0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
对比得出,下面的代码能够识别数组是否已经有序,减少了不必要的重复工作 。