赞
踩
目录
核心思想:两两相邻的元素相比较
通过图解原理我们可以发现规律(以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]);
- }
- }
运行结果如图,大家也可以用源码自己体验一下效果:
现在已经实现了冒泡排序,为了以后的方便,我们来试着将这个冒泡排序模块功能封装为一个函数。让我们一起来看看自定义为函数有那些坑。
按照上述排序规则和封装函数的方法,我们将数组作为一个函数参数,传递给冒泡排序函数来执行冒泡排序,我们来看一下:
- 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;
- }
思考:
对于这样一个有序数列,我们如果执行的话,我们的自定义函数就还是会跑一遍,那么这样实际效率并不高。所以想能不能改进一下我我们的代码。
再次浏览原理图,我们不难发现这样一个规律,只要数据是乱序一趟下来就会有元素在发生交换。
比如:
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;
- }
以上就是本期所有的内容,一些关于数组知识大家可以移步到数组文章再进行了解。欢迎大家的批评指正。希望和大家多交流学习。
和大家一起期待未来更好的自己加油!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。