引言
用c语言实现使用冒泡排序
一、什么是冒泡排序
冒泡排序是一种简单的排序算法
基本原理
- 冒泡排序的基本思想是通过对数组中相邻元素的比较和交换,将最大(或最小)的元素逐步 “冒泡” 到数组的末尾(或开头)。
- 它重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
单看这个原理可能不是很明白,那么看一下这个图,你就明白了:
(这是个升序排列的图)
二、用C语言实现冒泡排序
算法步骤
- 比较相邻的元素。如果第一个比第二个大(升序排序),就交换它们两个。(核心)
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。(核心)
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码示例
// 交换两个整数的函数 void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 冒泡排序函数 void bubbleSort(int arr[], int n) { int i, j; for (i = 0; i < n - 1; i++) //从前往后遍历数组还是从后往前遍历数组是没有影响的 { // 每一轮比较后,最大的元素会“浮”到数组末尾 for (j = 0; j < n - i - 1; j++) { // 如果当前元素大于下一个元素,则交换它们 //法一:自己写一个交换的函数 if (arr[j] > arr[j + 1]) { swap(&arr[j], &arr[j + 1]); //法二:搞个中间变量来完成交换 if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } } }
这里是用swap函数在实现交换的,因为是要交换数值大小,所以不能使用传值调用,要使用传址调用。
三、优化代码
试想:如果要让这个冒泡排序对已经有序的数组或者部分有序的数组来排列的话,上面的代码还是会全部执行一遍,这是完美没有必要的,这时可以优化排序的代码;
可以在每一轮开始的时候定义一个 int flag = 1,如果这一轮里交换了,就让flag = 0;
如果这一轮里没有交换第一对元素,说明是有序的,就让flag不变; 在这一轮里第一次交换完后判断,flag 是不是等于 1。
若等于 1 ,说明这一轮里后面是有序的,就break结束这一轮的循环,进入下一轮,接着排序。还是不懂的话,看着代码自己多想想。
优化后的代码:
// 冒泡排序函数(优化后的) void bubbleSort(int arr[], int n) { int i, j; for (i = 0; i < n - 1; i++) { // 每一轮比较后,最大的元素会“浮”到数组末尾 int flag = 1; for (j = 0; j < n - i - 1; j++) { // 如果当前元素大于下一个元素,则交换它们 if (arr[j] > arr[j + 1]) { flag = 0; swap(&arr[j], &arr[j + 1]); } if (flag == 1) //这⼀轮没交换就说明已经有序,后续⽆序排序了 break; } } }
四、算法分析
- 时间复杂度:
- 在最坏情况下,冒泡排序需要对数组进行 n−1 轮比较,每轮比较需要 n−i 次比较操作(i 表示当前轮数),所以时间复杂度为 O(n2)。
- 在最好情况下,数组已经有序,只需要进行 n−1 次比较,时间复杂度为 O(n)。
- 空间复杂度:冒泡排序只需要常数级的额外空间来进行元素的交换,所以空间复杂度为 O(1)。
- 稳定性:冒泡排序是一种稳定的排序算法,即相等的元素在排序前后的相对位置不会改变。
冒泡排序虽然简单,但对于小规模数据或基本有序的数据集合,它仍然是一种有效的排序方法。在实际应用中,可以根据具体情况选择合适的排序算法。