1.常见排序算法的时间和空间复杂度
算法 | 平均时间复杂度 | 最好时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O( n 2 n^2 n2) | O( n n n) | O( n 2 n^2 n2) | O( 1 1 1) | 稳定 |
快速排序 | O( n l o g n nlogn nlogn) | O( n l o g n nlogn nlogn) | O( n 2 n^2 n2) | O( n l o g n nlogn nlogn) | 不稳定 |
归并排序 | O( n l o g n nlogn nlogn) | O( n l o g n nlogn nlogn) | O( n l o g n nlogn nlogn) | O( l o g n logn logn) | 稳定 |
堆排序 | O( n l o g n nlogn nlogn) | O( n l o g n nlogn nlogn) | O( n l o g n nlogn nlogn) | O( 1 1 1) | 不稳定 |
希尔排序 | O( n l o g n nlogn nlogn) | O( n 1.3 n^{1.3} n1.3) | O( n 2 n^2 n2) | O( 1 1 1) | 不稳定 |
注意,对于冒泡排序,最坏的情况就是完全逆序,此时空间复杂度为 O ( n ) O(n) O(n)。
2.冒泡排序
1)算法流程
#include<stdio.h>
void swap(int &a,int &b);
int main()
{
int a[4]={5,6,3,1};
for(int i = 0;i<4;i++)
for(int j=0;j<4-i-1;j++)
if(a[j]>a[j+1])
swap(a[j],a[j+1];
return 0;
}
void swap(int &a,int &b)
{
int temp=a;
a = b;
b = temp;
}
冒泡排序的基本思想就是两两比较并按照规定交换,先确定数组中最后一个数的位置,也就是最大(或最小)的数。然后再一轮从头开始两两比较,确定倒数第二个位置的数字,依次类推,直到数组中的第一个数确定好,整个数组就是有序的了。
e.g: 5 6 3 1(期望正序:1 3 5 6—>
a
[
j
]
<
a
[
j
+
1
]
a[j]<a[j+1]
a[j]<a[j+1])
step1: 5与6比较,满足正序,不调整。整个数组:5 6 3 1
step2: 6与3比较,不满足正序,交换:5 3 6 1
step3: 6与1比较,不满足正序,交换:5 3 1 6
可以看到经过一轮交换,最大的数6到了数组的最后一个位置。
第二轮比较(从头开始)
step4: 5与3比较,不满足正序,交换:3 5 1 6
step5: 5与1比较,不满足正序,交换:4 1 5 6
注意,此时不需要再将5与6比较,因为上一轮我们已经确定了数组最后一个位置的数(也就是全局最大的数),再比较也肯定不会产生交换动作,所以内层循环结束条件是j<n-i-1
,减1是为了a[j+1]
不越界。
第三轮比较(从头开始)
step6: 4与1比较,不满足正序,交换:1 4 5 6。
因为前两轮我们已经确定了最后两个数字的位置且不会再改变了,所以没有接着往下比较的必要,此时倒数第三个位置的数字也确定了下来。
所以最后只剩下第一个位置,也自然的就确定了下来:1 4 5 6
排序结束。
2)例题:对输入的n个数进行排序
样例输入:
4
1 4 3 2
样例输出:
1 2 3 4
来源:
2006华中科技大保研机试真题
思路分析:
-
复杂度分析
时间限制是1s,所以数量级最大为1000万级别,因为题目中的n取值范围不大于100,所以即使采用O( n 2 n^2 n2)的算法,如冒泡排序,时间复杂度最多也只是一万,符合要求。
内存限制32M,因为冒泡排序最坏即完全逆序的情况下的空间复杂度为 O ( n ) O(n) O(n),所以最大内存占用: 100 ∗ 32 b i t 100*32bit 100∗32bit(申请一个 i n t int int n [ 100 ] n[100] n[100]的数组空间),也是符合要求的,所以本题用最简单的冒泡排序也是可以顺利通过的。
#include<stdio.h>
void swap(int &a,int &b)
{
int temp=a;
a = b;
b = temp;
}
int main()
{
int a[103],n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
//冒泡排序
for(int i=0;i<n;i++)
for(int j=0;j<n-i-1;j++)
{
if(a[j]>a[j+1])
swap(a[j],a[j+1]);
}
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}
return 0;
}
结果: