一、冒泡排序
原理:依次比较相邻的两个数,将较小的数放在前面,较大的数放在后面
举例:[9,1,34,61,89,36,52]
第一趟
1. [1|,9,34,61,89,36,52] (比较1和9,确定1的位置)
2. [1,9|,34,61,89,36,52] (比较9和34,确定9的位置)
3. [1,9,34|,61,89,36,52] (比较34和61,确定34的位置)
4. [1,9,34,61|,89,36,52] (比较61和89,确定61的位置)
5. [1,9,34,61,36|,89,52] (比较89和36,确定36的位置)
6. [1,9,34,61,36,52|,89] (比较89和52,确定52的位置)
最终确定最大值89
第二趟
1. [1|,9,34,61,36,52,89] (比较1和9,确定1的位置)
2. [1,9|,34,61,36,52,89] (比较9和34,确定9的位置)
3. [1,9,34|,61,36,52,89] (比较34和61,确定34的位置)
4. [1,9,34,36|,61,52,89] (比较61和36,确定36的位置)
5. [1,9,34,36,52|,61,89] (比较52和61,确定52的位置)
最终确定第二大的值61
......以此类推
第六趟
1. [1,9,34,36,52,61,89] (比较1和9,确定1的位置)
最终确定第六大的值9
则最小值不用比较,直接为1
推广:假设一共有n个数字,要比较n-1趟,每趟要比较n-i次,一共要比较n*(n-1)/2次
时间复杂度为:O(n2) 具有稳定性
代码实现:
/*冒泡排序*/
#include <stdio.h>
void main()
{
int a[100], i, j, k, t, n;
printf("Input n:\n");
scanf("%d", &n);
printf("Input nums:\n");
for (i = 1; i <= n; i++)
scanf("%d", &a[i]);
printf("\n");
for (j = 1; j <= n - 1; j++)
{
for (i = 1; i <= n - j; i++)
{
if (a[i] > a[i + 1])
{
t = a[i];
a[i] = a[i + 1];
a[i + 1] = t;
}
for (k = 1; k <= n; k++)
{
printf("%d ", a[k]);
}
printf("\n");
}
}
printf("The sorted numbers:\n");
for (i = 1; i <= n; i++)
printf("%d ", a[i]);
}
二、选择排序
原理:每一轮选择最小项与第一位交换
(假设a[1]是最小项min,比较所有数据得出最小项a[x],若1!=x,则交换)
举例:[9,1,34,61,89,36,52]
1. [1|,9,34,61,89,36,52] (最小值1与9交换,确定1的位置)
2. [1,9|,34,61,89,36,52] (最小值9不换,确定9的位置)
3. [1,9,34|,61,89,36,52] (最小值34不换,确定34的位置)
4. [1,9,34,36|,89,61,52] (最小值36与61交换,确定36的位置)
5. [1,9,34,36,52|,61,89] (最小值52与89交换,确定52的位置)
6. [1,9,34,36,52,61|,89] (最小值61不换,确定61的位置)
推广:假设一共有n个数字,要比较n-1趟,每趟要比较n-i次确定最小值
时间复杂度为:O(n2) 不具有稳定性
代码实现:
#include <stdio.h>
void main()
{
int a[100], i, j, min, t,k, n;
printf("Input n:\n");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
printf("Input nums:\n");
for (i = 1; i <= n - 1; i++)
{
k = i;
for (j = i + 1; j <= n; j++) //选择
if (a[j] < a[k])
k = j;
if (i != k) //交换
{
t = a[i];
a[i] = a[k];
a[k] = t;
}
}
printf("The sorted numbers:\n");
for (i = 1; i <= n; i++)
printf("%d ", a[i]);
}
三、快速排序
原理:把小于基准元素的值放在左边,大于基准元素的值放在右边
(假定左边第一个为基准元素,则L指向左一,R指向右一,从右边的R开始向中间移动,若R指向元素大于基准元素,则不移动元素,R向前一位;若该元素小于基准元素,则将其元素移至左一L的指向处,开始移动左边L,若元素小于基准则前移L,反之将元素移至右边R处,以此类推,直至L、R重合,则将基准元素移至此处。确定基准元素后,再同样处理其左边和右边的数,直至全部有序)
举例:[9,1,34,61,89,36,52]
1. 9 [ * ,1,34,61,89,36,52*] (以9为基准元素,L指向左空,R指向右52)
9 [ * ,1*,34,61,89,36,52] (R从右往左移动,直到R指向1,1<9,将1移至L指向位)
9 [1*, *,34,61,89,36,52] (1<9,L右移,则L、R重合,将9放在此位)
[1,9,34,61,89,36,52]
2. [1,9,34,61,89,36,52] (1有序,则将9右边数列排序)
34 [1,9,* ,61,89,36,52*] (以34作为基准元素,L指左空,R指右52)
34 [1,9,* *,61,89,36,52] (R从右往左移动,直到R与L重合,将34放在此位)
[1,9,34,61,89,36,52] (最小值61不换,确定61的位置)
3. 61 [1,9,34,* ,89,36,52*] (将61作为基准元素,L指左空,R指右52)
61 [1,9,34,* ,89,36,52*] (52<61,将52移至L处)
61 [1,9,34,52,*89,36, *] (L从左开始移动,89>61,将89移至右R)
61 [1,9,34,52,* ,36*,89] (R开始前移,36<61,将36移至左L)
61 [1,9,34,52,*36, *,89] (L开始前移,直至L、R重合)
[1,9,34,52,36,61,89]
4. [1,9,34,52,36, 61,89] (89有序,则左边排序)
52 [1,9,34,* ,36*, 61,89] (以52为基准,左L右36R)
52 [1,9,34,* ,36*, 61,89] (36<52,移至左L)
52 [1,9,34,*36, *, 61,89] (左L前移,直至L、R重合)
[1,9,34,36 ,52, 61,89]
推广:假设一共有n个数字 平均时间复杂度为:O(Nlog2N) 不具有稳定性
代码实现: