【大白话】C语言冒泡排序算法:让数组“水底捞月”

【大白话】C语言冒泡排序算法:让数组“水底捞月”目录冒泡排序算法原理冒泡排序算法时间复杂度和空间复杂度冒泡排序算法稳定性C语言代码实现冒泡排序算法的应用场景面试题废话不多说,先上一张动图,方便

大家好,欢迎来到IT知识分享网。

目录

  1. 冒泡排序算法原理
  2. 冒泡排序算法时间复杂度和空间复杂度
  3. 冒泡排序算法稳定性
  4. C语言代码实现
  5. 冒泡排序算法的应用场景
  6. 面试题

废话不多说,先上一张动图,方便大家理解冒泡的流程步骤,后边会逐步解析

【大白话】C语言冒泡排序算法:让数组“水底捞月”

1. 冒泡排序算法原理

冒泡排序是一种基础的排序算法,它的核心思想是比较相邻的元素,如果顺序错误就交换它们的位置。这个过程就像是把一堆气泡从底部往上推,把小的气泡慢慢往上冒,最后达到从小到大的排序效果。

例如,我们有一个数组{5, 3, 8, 4, 2},按照冒泡排序的过程,会依次比较相邻的元素:

  • 第一次比较,5和3进行比较,因为5>3,所以交换它们的位置,数组变成{3, 5, 8, 4, 2}
  • 第二次比较,5和8进行比较,因为5<8,不需要交换位置,数组不变
  • 第三次比较,8和4进行比较,因为8>4,所以交换它们的位置,数组变成{3, 5, 4, 8, 2}
  • 第四次比较,8和2进行比较,因为8>2,所以交换它们的位置,数组变成{3, 5, 4, 2, 8}

经过第一轮排序,最大的数8已经被排到了最后面。接下来进行第二轮排序,只需要比较前四个元素即可。依次类推,直到所有元素都被排序。

2. 冒泡排序算法时间复杂度和空间复杂度

假设有一个由大小为6的整数数组 {5, 2, 4, 6, 1, 3},我们需要对它进行冒泡排序。根据冒泡排序的算法。

第一轮比较我们需要将5和2进行比较,然后将它们交换位置,得到数组 {2, 5, 4, 6, 1, 3};

接下来比较5和4,交换得到数组 {2, 4, 5, 6, 1, 3};

然后是5和6比较,无需交换位置;

接着是6和1比较,交换位置得到数组 {2, 4, 5, 1, 6, 3};

接下来是6和3比较,交换位置得到数组 {2, 4, 5, 1, 3, 6}。

第一轮排序结束后,我们可以得到最大的数字6被排好序到最后,接下来只需要将 {2, 4, 5, 1, 3} 这个小数组再次执行冒泡排序即可。

第二轮比较,我们需要将2和4进行比较,无需交换位置;接着是4和5比较,无需交换位置;然后是5和1比较,交换位置得到数组 {2, 4, 1, 5, 3, 6};接下来是5和3比较,交换位置得到数组 {2, 4, 1, 3, 5, 6}。现在,除去已经排序好的6,我们已经将整个数组的第二大数字5排好序到了正确的位置,只要再将 {2, 4, 1, 3} 再次执行冒泡排序即可。

第一轮排序结束后,我们可以得到最大的数字6被排好序到最后,接下来只需要将 {2, 4, 5, 1, 3} 这个小数组再次执行冒泡排序即可。

第二轮比较,我们需要将2和4进行比较,无需交换位置;接着是4和5比较,无需交换位置;然后是5和1比较,交换位置得到数组 {2, 4, 1, 5, 3, 6};接下来是5和3比较,交换位置得到数组 {2, 4, 1, 3, 5, 6}。现在,除去已经排序好的6,我们已经将整个数组的第二大数字5排好序到了正确的位置,只要再将 {2, 4, 1, 3} 再次执行冒泡排序即可。

对于这个例子,我们可以发现,进行冒泡排序最多需要执行 n−1 轮排序,每轮排序需要比较n−i 次,正好是一个等差数列的求和公式,所以冒泡排序的时间复杂度是 O(n2)。除了原数组外,排序时我们可能会创建一个临时变量来保存交换的数值,所以冒泡排序的空间复杂度是 O(1),是一种空间复杂度比较低的排序算法。

3. 冒泡排序算法稳定性

冒泡排序算法是一种稳定的排序算法。所谓稳定性,就是指对于相等的元素,在排序前后它们的相对位置不变。也就是说,如果在我们要排序的数组中有多个值相同的元素,那么在排序前后,这些元素的相对位置是不会被改变的。

冒泡排序算法的稳定性来源于它的比较和交换操作。在实现冒泡排序时,我们通过比较相邻两个元素的大小关系来决定是否需要交换它们的位置,如果相邻两个元素大小相同,那么我们是不会交换它们的位置的,因此,相等的元素不会改变它们在数组中的相对位置。

所以,冒泡排序算法是一种稳定的排序算法。这也是为什么它在某些场合被称为“泡沫排序”,因为“冒泡”和“泡沫”都有一种涨起来又落下去的感觉。

4. C语言代码实现

下面是C语言实现冒泡排序算法的代码:

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]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }

代码中使用了双重循环,外层循环控制比较的轮数,内层循环进行具体的比较和交换操作。

5. 冒泡排序算法的应用场景

冒泡排序虽然时间复杂度较高,但在某些场景下,其实际表现仍然比较优秀。以下是一些常见的应用场景:

  1. 数据量较小:对于小规模的数据排序,冒泡排序的表现要比其他排序算法好得多,因为其代码简单,无需额外的空间存储数据。
  2. 数据基本有序亦可:如果要排序的数据已经基本有序,只有极少数位置需要交换,那么冒泡排序的表现也非常出色,因为经过一轮冒泡操作后,大多数数据都已经就位了。
  3. 数据元素较为简单:如果要排序的数据类型很简单,而且数据的存储方式也较为简单,冒泡排序的性能往往很不错。比如对一个字符数组按照字典序排序,或者对整型数组按照从小到大排序。

总之,冒泡排序适用于一些小规模、基本有序、数据元素简单的排序场景。当然,对于较大规模、乱序、复杂元素的数据排序,更可以采用其他高效的排序算法,例如快速排序、归并排序等。

面试题扩展

Q: 请编写一个函数,使用冒泡排序算法对一个整型数组进行排序,要求使用两种方法实现,一种是普通的冒泡排序算法,另一种是改进后的冒泡排序算法,并对两种算法的时间复杂度和优化效果进行分析。

提示:可以先写出普通的冒泡排序算法,然后再根据其性能瓶颈进行优化,以达到更高的效率。

欢迎读者在评论区讨论解法!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/48616.html

(0)
上一篇 2024-09-07 19:00
下一篇 2024-09-07 20:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信