1、交换排序
a、冒泡排序
1 #include <stdio.h> 2 int main() { 3 int a[] = {4, 0 , 2, 3, 1}, i, j, t; 4 for(i=4; i>=0; i--) { 5 for(j=0; j<i; j++) { 6 if(a[j]>a[j+1]) { 7 t=a[j]; 8 a[j]=a[j+1]; 9 a[j+1]=t; 10 } 11 } 12 } 13 for(i=0;i<5;i++){ 14 printf("%d ",a[i]); 15 } 16 }
分析:
(1)冒泡排序的思路是每次比较相邻的两个数,把最大的数放到最后
(2)上面的代码效率较低,因为若数组已经有序的话循环不会停,可加个变量解决
(3)效率:最好O(N),最差O(N2);与逆序对个数成正比
(4)优点:操作简单,适应性好,如数据放在单向链表中时;稳定
1 #include <stdio.h> 2 int main() { 3 int a[] = {4, 0 , 2, 3, 1}, i, j, t,flag; 4 for(i=4; i>=0; i--) { 5 flag = 0; 6 for(j=0; j<i; j++) { 7 if(a[j]>a[j+1]) { 8 t=a[j]; 9 a[j]=a[j+1]; 10 a[j+1]=t; 11 flag = 1; 12 } 13 } 14 if(flag==0) break; 15 } 16 for(i=0;i<5;i++){ 17 printf("%d ",a[i]); 18 } 19 }
一种错误的写法:
1 #include <stdio.h> 2 int main() { 3 int a[] = {4, 0 , 2, 3, 1}, i, j, t; 4 for(i=0; i<5; i++) { 5 for(j=0; j<5-i; j++) { 6 if(a[j]>a[j+1]) { 7 t=a[j]; 8 a[j]=a[j+1]; 9 a[j+1]=t; 10 } 11 } 12 } 13 for(i=0;i<5;i++){ 14 printf("%d ",a[i]); 15 } 16 }
分析:第5行的5应为4
2、插入排序
1 #include <stdio.h> 2 int main() { 3 int a[] = {4, 0 , 2, 3, 1}, i, j, t; 4 for (i = 1; i < 5; i++) { 5 t = a[i]; 6 j = i - 1; 7 while (j >= 0 && t > a[j]) { 8 a[j+1] = a[j]; 9 j--; 10 } 11 a[j+1] = t; 12 } 13 }
分析:
(1)插入排序的原理类似摸扑克牌,如扑克按升序排列,每次摸到一张新牌后,都要与现有的所有牌做比较然后插到合适的位置。如果你一开始摸牌就这样做的话,你手中的牌就一直是有序的,只需把每次的新牌插到合适位置即可
(2)t就是新牌,while中是新牌与老牌比较的过程,i和j是双指针,一个指向新牌,一个遍历老牌
(3)边界条件,如果新牌比老牌都小,j最后等于-1,11行就是把新牌放到a0位置
(4)效率:最好O(N),最差O(N2);与逆序对个数成正比
(5)优点:稳定
3、选择排序
a、堆排序
4、归并排序
优点:快
缺点:需要额外空间,一般用于外排序