冒泡排序、插入排序、选择排序

本文深入探讨了排序算法的评价标准,包括执行效率、内存消耗及稳定性,并详细解析了冒泡排序、插入排序和选择排序的特点与应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是排序?

这个就不说了

如何评价排序?

我们规定下定义一个排序算法好坏的维度。

1.执行效率

这里对于效率的概念可以分为两部分,一部分是执行时间,另一部分就是比较和交换的次数(也可以归结到时间里去)。

时间其实就是时间复杂度,很好理解,就是时间复杂度越小的算法,我们认为越好。

 

比较和交换的次数我们后续会引入一个概念叫做有序度逆序度

这个有序度逆序度是一个对的概念。每次只比较一对数字。有序即左小右大,逆序即左大右小。

还有一个满有序度(即完全排好的),可想而知满有序度 = n*(n-1)/2 = 有序度+逆虚度

 

2.内存消耗

消耗内存空间的大小其实就是空间复杂度的概念,这里引入一个概念叫原地排序(我不动),简单来说就是空间复杂度O(1)的排序算法。

 

 

3.是否稳定

是否稳定的意思就是,比如说我两个相同的数字还要不要换位置。我们把不需要换位置的算法称为稳定算法,需要换的算法称为不稳定算法

 

冒泡排序

冒泡排序每次只涉及相邻的2个元素,两个元素互排,然后一路向上,直到上面比你大为止。然后每个元素执行相同的操作。

 

最好时间复杂度O(n),最坏时间复杂度O(n2)(我比较完你比较),平均时间复杂度O(n2)。

空间复杂度O(1),原地排序算法,因为每次只涉及两个元素的交换操作。

是稳定排序算法,遇到相同不交换。

 

总结下,冒泡排序就是一个交换的算法。

 

插入排序

插队排序引入了一个方法,就是将数据集分为已排序区间未排序区间。然后从未排序区间依次取元素差到已排序区间中。对于相同的元素,插到已经存在于已排序区间元素的后面

插入排序涉及插入移动

 

最好的时间复杂度O(n),最坏的时间复杂度O(n2),平均时间复杂度O(n2)。

空间复杂度O(1),原地排序算法。

稳定排序算法,遇到不交换。

 

选择排序

选择排序其实是插入排序的另一个版本。同插入排序一样,也有已排序区间未排序区间。但是从未排序区间的取数方式不是按次了,而是按最小值。对于相同的元素,插到已经存在于已排序区间元素的前面。

同插入排序一致,选择排序涉及插入移动

 

最好的时间复杂度是O(n2),最坏的时间复杂度O(n2),平均时间复杂度O(n2)。

空间复杂度O(1),原地排序算法。

不稳定排序算法。

 

补充

冒泡排序和插入排序的交换次数等于原数据的逆序度

插入排序的升级版本,希尔排序

 

 

参考

排序算法的稳定性及其意义:https://blog.youkuaiyun.com/u012501054/article/details/79342580

 

 

 

 

 

 

### C语言中冒泡排序插入排序选择排序的实现方法 #### 1. 冒泡排序 冒泡排序的核心思想是比较相邻的两个元素,如果前一个元素大于后一个元素,则交换它们的位置。通过多次遍历数组,最终可以将最大的元素逐步移动到数组的最后面。 以下是冒泡排序的具体实现: ```c void bubbleSort(int arr[], int n) { for (int i = 0; i < n - 1; i++) { // 控制轮数 for (int j = 0; j < n - 1 - i; j++) { // 每一轮减少比较次数 if (arr[j] > arr[j + 1]) { // 如果前面的元素大于后面的元素则交换 int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } ``` 上述代码实现了基本的冒泡排序逻辑[^3]。 --- #### 2. 插入排序 插入排序的思想是构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。具体来说,每次取一个新元素,将其插入到之前已经排好序的部分中。 以下是插入排序的具体实现: ```c void insertionSort(int arr[], int n) { for (int i = 1; i < n; i++) { // 假设第一个元素已经是有序部分 int key = arr[i]; // 当前要插入的元素 int j = i - 1; while (j >= 0 && arr[j] > key) { // 找到合适的位置 arr[j + 1] = arr[j]; // 向右移动较大的元素 j--; } arr[j + 1] = key; // 将当前元素插入到正确位置 } } ``` 这段代码展示了如何利用循环和条件判断完成插入排序的过程[^2]。 --- #### 3. 选择排序 选择排序的主要思路是在每一步中从未排序部分选出最小(或最大)的元素,并将其放置在已排序部分的末尾。这样经过若干步操作之后,整个数组就会变得有序。 下面是选择排序的一个典型例子: ```c void selectionSort(int arr[], int n) { for (int i = 0; i < n - 1; i++) { // 需要进行n-1次选择操作 int minIndex = i; // 记录最小值索引 for (int j = i + 1; j < n; j++) { // 寻找第i小的元素 if (arr[j] < arr[minIndex]) { minIndex = j; // 更新最小值索引 } } if (minIndex != i) { // 若发现更小的值,则交换两者 int temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } } } ``` 此版本的选择排序能够有效地定位每一个待处理阶段中的极值项。 --- ### 总结 以上分别介绍了三种经典排序算法——冒泡排序插入排序以及选择排序的概念及其对应的C语言程序片段。这些基础排序技术虽然效率未必是最优解法之一,但对于初学者理解和掌握计算机科学领域内的基础知识非常重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值