pre
简单排序:冒泡,选择,插入
高级一点:快排,堆排,基数排,希尔排
2015.4.30完成前三个,5.3后四个补坑啊
0 main函数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define N 10
void bubble();
void selectsort();
void insertsort();
int main(int argc, const char * argv[]) {
bubble();
selectsort();
insertsort();
return 0;
}
1 bubble sort
最简单的排序 —— [ 维基百科 ]
算法思想
- 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
时间复杂度:o(n^2)
比较次数为 (n-1) + (n-2) + … + 1 = n * (n - 1) / 2
最坏情况移动次数:
最坏情况是把顺序的排列变成逆序,或者把逆序的数列变成顺序。在这种情况下,每一次比较都需要进行交换运算。
code
void bubble(){
// bubble sort 从小到大排序,大的沉底
int a[N]={0};
int i=0,j=0,tmp=0;
clock_t begin=0,end=0;
printf("before bubble sort:");
for (i=0; i<N; i++) {
a[i]=rand()%100;
printf("%4d",a[i]);
}
printf("\n");
begin=clock();
for (i=0; i<N; i++) {
for (j=0; j+1<N-i; j++) { //注意这里j+1<N-i 保证j+1不越界
if (a[j]>a[j+1]) {
tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
}
}
}
end=clock();
printf("the bubble sort time:%.15f\n",(float)(end-begin)/CLOCKS_PER_SEC);
printf("after bubble sort: ");
for (i=0; i<N; i++) {
printf("%4d",a[i]);
}
printf("\n");
}
2 select sort
算法思想
每一趟比较选出min或max的,n趟后n个数有序。
时间复杂度:
比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+…+1=n*(n-1)/2。
交换次数O(n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快
code
void selectsort(){
//选择排序
int a[N]={0};
int i=0,j=0,tmp=0;
clock_t begin=0,end=0;
printf("before select sort:");
for (i=0; i<N; i++) {
a[i]=rand()%100;
printf("%4d",a[i]);
}
printf("\n");
begin=clock();
int min_index=0;
for (i=0 ; i<N-1; i++) {
min_index=i;
for (j=i; j<N; j++) {
if (a[j]<a[min_index]) {
min_index=j;
}
}
tmp=a[i];
a[i]=a[min_index];
a[min_index]=tmp;
}
end=clock();
printf("the select sort time:%.15f\n",(float)(end-begin)/CLOCKS_PER_SEC);
printf("after select sort: ");
for (i=0; i<N; i++) {
printf("%4d",a[i]);
}
printf("\n");
}
3 insert sort
算法思想
对冒泡排序的改进,基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
时间复杂度: O(n^n)
code
void insertsort(){
//插入排序
int a[N]={0};
clock_t begin=0,end=0;
int index=0; //表示下标
int insert_pos=0; //插入位置下标
int index_move=0; //需要移动元素的下标
int tmp=0; //用于移动过程保存元素
int i=0; //用于循环打印等的计数变量
printf("before insert sort:");
for (i=0; i<N; i++) {
a[i]=rand()%100;
printf("%4d",a[i]);
}
printf("\n");
begin=clock(); //时间统计函数
for (index=1 ; index<N; index++) {
tmp=a[index]; //保存当前位置元素
for (insert_pos=0; insert_pos<index; insert_pos++) {
if (a[insert_pos]>tmp) {
break;
}
}
if (insert_pos<index) {
//insert_pos<index表明是由break 跳出找到插入位置,前方元素须后移,若insert_pos=index,表明不须移动
for (index_move=index-1; index_move>=insert_pos; index_move--) {
a[index_move+1]=a[index_move];
}
a[insert_pos]=tmp;
}
}
end=clock();
printf("the insert sort time:%.15f\n",(float)(end-begin)/CLOCKS_PER_SEC);
printf("after insert sort: ");
for (i=0; i<N; i++) {
printf("%4d",a[i]);
}
printf("\n");
}