十大排序算法之冒泡与快排
因为刚刚接触编程语言这方面,基础很薄弱,之前的算法和思维都是靠硬背下来,到真正应用时真的非常头疼。现在有时间于是整理了如下笔记,今天先记录最早接触的冒泡排序和快速排序,两种排序方法得出的序列都是从小到大。
- 当一个序列是基本有序时,快速排序和冒泡排序间应当选择冒泡排序。
冒泡排序
基本原理
通过相邻的元素两两比较,若 i-1 > i,则交换 i-1 与 i 的位置;否则,不交换。因此排序完成后的次序是从小到大的,像是小的元素像泡一样浮上水面,故称为冒泡排序。
排序的序列是逆序时,冒泡排序的最好情况的时间效率为O(n)。
冒泡排序的核心是相邻元素的比较和交换,因此是一种稳定排序的算法。
#include <stdio.h>
#define ARR_LEN 255 /*数组长度上限*/
#define elemType int /*元素类型*/
/* 冒泡排序 */
/* 1. 从当前元素起,向后依次比较每一对相邻元素,若逆序则交换 */
/* 2. 对所有元素均重复以上步骤,直至最后一个元素 */
/* elemType arr[]: 排序目标数组; int len: 元素个数 */
void bubbleSort (elemType arr[], int len) {
elemType temp;
int i, j;
for (i=0; i<len-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
for (j=0; j<len-1-i; j++) { /* 内循环为每趟比较的次数,第i趟比较len-i次 */
if (arr[j] > arr[j+1]) { /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
int main (void) {
elemType arr[ARR_LEN] = {3,5,1,-7,4,9,-6,8,10,4};
int len = 10;
int i;
bubbleSort (arr, len);
for (i=0; i<len; i++)
printf ("%d\t", arr[i]);
putchar ('\n');
return 0;
}
快速排序
基本原理
1.从序列中取一个数x,以x为标准,从最右边开始找,将序列中比x小的放在左边;从左边开始找比x大的放在右边;
2.左右区间重复步骤1;
3.当各区间只剩一个数,排序结束。
例如:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
72 | 14 | 23 | 45 | 88 | 32 | 19 | 23 | 3 |
取72为x, i = 0; j = 8;
从 j 往前找,当 j = 8时,3 < 72 ,则将72移出,将3填入,即
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
3 | 14 | 23 | 45 | 88 | 32 | 19 | 23 |
此时第8个数为空,则从 i 开始往前找,当 i = 4时,88>72,则将88放入 i = 8中:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
3 | 14 | 23 | 45 | 32 | 19 | 23 | 88 |
此时 i=4 , j=7 ,则从 j = 7开始重复以上步骤
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
3 | 14 | 23 | 45 | 23 | 32 | 19 | 88 | |
– | – | – | – | – | – | – | – | – |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
3 | 14 | 23 | 45 | 23 | 32 | 19 | 72 | 88 |
一趟排序便完成了。自此分为左右两个区间,每个区间再重复以上步骤,可得到从小到大的有序序列。
快速排序的最好情况是每次划分都能均匀划分,时间效率为O(nlogn).
快速排序的最坏情况是完全倒序时,时间效率为O(n^2).
//源代码在菜鸟教程
//快速排序
void quick_sort(int s[], int l, int r)
{
if (l < r)
{
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = l, j = r, x = s[l];
while (i < j)
{
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
s[i++] = s[j];
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j--] = s[i];
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}