目录
核心思想:两两相邻的元素相比较
1,冒泡排序原理(图解)
2.冒泡排序实现
通过图解原理我们可以发现规律(以10个元素排列举例)
1.每一趟比较完全完成就把这一趟数据的最大数放在最后,第一趟是10个数据中的最大值9在最后,第二趟是9个数据中的8在最后,那么我们10个元素就要循环9趟,那么n个数据,就要循环n - 1趟。
2.第一趟是10个数据,就有9对数据比较,那么第二趟,就有8对数据进行比较。如果一趟有n个数据就要比较n - 1对数据。
3.所以需要两层循环,外层控制趟数,内层控制每一趟要比较的次数。
看如下实现。
int main()
{
int len[10] = { 0 };
int i = 0;
for (i = 0; i < 10; i++)
{
scanf("%d",&len[i]);
}
int n = sizeof(len) / sizeof(len[0]);
//printf("%d", n);
int x = 0;
for (x = 0; x < n; x++)
{
int y = 0;
{
for (y = 0; y < n-1 - x; y++)
{
if (len[y] > len[y + 1])
{
int temp = 0;
temp = len[y];
len[y] = len[y + 1];
len[y + 1] = temp;//交换
}
}
}
}
int j = 0;
for (j = 0; j < 10; j++)
{
printf(" %d ", len[j]);
}
}
运行结果如图,大家也可以用源码自己体验一下效果:
3.冒泡排序封装为函数
现在已经实现了冒泡排序,为了以后的方便,我们来试着将这个冒泡排序模块功能封装为一个函数。让我们一起来看看自定义为函数有那些坑。
按照上述排序规则和封装函数的方法,我们将数组作为一个函数参数,传递给冒泡排序函数来执行冒泡排序,我们来看一下:
void BBurd_sort(int arr[10])
{
int n= sizeof(arr) / sizeof(arr[0]);
int x = 0;
for (x = 0; x < n; x++)
{
int y = 0;
{
for (y = 0; y < n - 1 - x; y++)
{
if (arr[y] > arr[y + 1])
{
int temp = 0;
temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;//交换
}
}
}
}
}
int main()
{
int arr[10] = { 0 };
int i = 0;
for (i = 0; i < 10; i++)
{
scanf("%d", &arr[i]);
}
//int sz = sizeof(arr) / sizeof(arr[0]);
BBurd_sort(arr);
int j = 0;
for (j = 0; j < 10; j++)
{
printf(" %d ", arr[j]);
}
return 0;
}
我们观察到没有发生排序,我们调试看一下:
问题所在:我们这里想要实现的功能是n 保存的是数组的大小,那么应该是10才对,为什么是2呢。
思考:sizeof(arr[0] 求的是一个整形数组元素的大小那么其大小就应该是4字节,
那么说明我们的sizeof(arr)就是8字节,那么只有可能我们这里的arr,并不是一整个数组,而是一个地址 (地址也就是指针,在32位操作系统下面大小是4个字节,64位操作系统下是8个字节),那就说明我们这里的arr实质上是一个指针,保存的是数组首元素的地址。
所以在函数里面是没有办法求出这个数组的大小,解决办法,把函数的大小作为一个函数的参数一起传递,看一下改进效果。
程序正常实现,附上源码。大家体验一下效果。
void BBurd_sort(int arr[10], int n)
{
int x = 0;
for (x = 0; x < n; x++)
{
int y = 0;
{
for (y = 0; y < n-1 - x; y++)
{
if (arr[y] > arr[y + 1])
{
int temp = 0;
temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;//交换
}
}
}
}
}
int main()
{
int arr[10] = { 0 };
int i = 0;
for (i = 0; i < 10; i++)
{
scanf("%d", &arr[i]);
}
int sz = sizeof(arr) / sizeof(arr[0]);
BBurd_sort(arr, sz);
int j = 0;
for (j = 0; j < 10; j++)
{
printf(" %d ", arr[j]);
}
return 0;
}
4.冒泡排序代码效率改进。
思考:
对于这样一个有序数列,我们如果执行的话,我们的自定义函数就还是会跑一遍,那么这样实际效率并不高。所以想能不能改进一下我我们的代码。
再次浏览原理图,我们不难发现这样一个规律,只要数据是乱序一趟下来就会有元素在发生交换。
比如:
9 1 2 3 4 5 6 7 8
这样的数据,第一趟会有元素交换,第二趟就没有。
那么我们可以这样,只要某一趟没有交换,说明此时我们的数列已经有序了就跳出
只要发生交换就继续。
那么看一下改进代码:
void BBurd_sort(int arr[10], int n)
{
int x = 0;
for (x = 0; x < n; x++)
{
int flag = 0;
int y = 0;
for (y = 0; y < n-1 - x; y++)
{
if (arr[y] > arr[y + 1])
{
int temp = 0;
temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;//交换
flag = 1;//发生了交换就改变flag
}
}
//执行完一趟就判断一下有没有交换,有交换就继续,没有交换就直接退出,不用排序了
if (flag == 0)
{
break;
}
}
}
int main()
{
int arr[10] = { 0 };
int i = 0;
for (i = 0; i < 10; i++)
{
scanf("%d", &arr[i]);
}
int sz = sizeof(arr) / sizeof(arr[0]);
BBurd_sort(arr, sz);
int j = 0;
for (j = 0; j < 10; j++)
{
printf(" %d ", arr[j]);
}
return 0;
}
以上就是本期所有的内容,一些关于数组知识大家可以移步到数组文章再进行了解。欢迎大家的批评指正。希望和大家多交流学习。
和大家一起期待未来更好的自己加油!