一、设计思想
1、我们可以把冒泡排序理解为不断地将大数向后移动,小数向前移动的过程。
2、举例
(1)先定义两个变量 i 和 j ,初始状态都在0的位置,让 j 和 j + 1 位置的数据进行比较,如果 j 大,就进行数据交换,如果 j + 1大就不移动,一直 j++,直到这一趟更便利结束。
(2)让 i ++,每进行一趟就++一次,原因是,我们用 i 来控制每一趟已经处理的已排序的个数。
(3)那问题是我们如何让j在已经排序好的元素前退出循环呢???
也就是在循环中 j 的边界值怎么算?
即j < len - i - 1;
二、代码
#include<stdio.h>
void BubbleSort(int arr[], int len)
{
int i = 0;
int j = 0;
int tmp = 0;
for (i; i < len-1 ; i++)
{
for (j = 0; j < len - i - 1; j++ )
{
if (arr[j + 1] < arr[j])
{
tmp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = tmp;
}
}
}
}
int main()
{
int arr[] = { 12, 3, 21, 32, 1, 34, 12, 35, 34 };
int len = sizeof(arr) / sizeof(arr[0]);
BubbleSort(arr, len);
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
三、优化
优化 1:
如果数据在i = n 时已经排序完成,但是按照常规来说,数据要继续进行n +1 次等等。该如何解决??
方法:我们设置一个标记位flag = 0,如果进行交换就让标记位flag = 1,我们在加一个判断语句,如果flag = 0,说明没有进行交换,就退出循环。这样就可以防止在排序完成后,还继续进行外层循环的情况。
void BubbleSort(int arr[], int len)
{
int i = 0;
int j = 0;
int tmp = 0;
int flag = 0;//标记发生交换
for (i; i < len-1 ; i++)
{
int flag = 0;
for (j = 0; j < len - i - 1; j++ )
{
if (arr[j + 1] < arr[j])
{
tmp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = tmp;
flag = 1;
}
}
if (flag = 0)//判断是否发生交换
{
break;
}
}
}
优化 2:
如果在一个数据中前面是无序的,而后面是有序的,那我们在用优化1进行操作时,每次前面部分都会进行交换数据,所以循环不会退出,我们怎样能让循环只进行前面无序数据的排序???
方法:在设置一个标志位pos = 0,每次把交换的下标 j 赋值给pos,直到最后一个交换位,让最后让pos = len - 1,这样i在进行判断时,只会执行到len - 1的位置。这样就有效防止了没有必要的交换判断。
void BubbleSort(int arr[], int len)
{
int i = 0;
int j = 0;
int tmp = 0;
int pos = 0;
int k = len - 1;
int p = 1;
for (i; i < k ; i++)
{
int flag = 0;
for (j = 0; j < len - i - 1; j++ )
{
if (arr[j + 1] < arr[j])
{
tmp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = tmp;
flag = 1;
pos = j;
}
}
k = pos;
if (flag = 0)
{
break;
}
}
}