归并排序:
归并的思想是将数据二分,然后两边再各自排序,最后再合并处理。其中心思想也是分治。
#include <stdio.h>
#include <string.h>
char copy[128];//合并时候需要的缓存
void swap(char *a, char *b)
{
char tmp = *a;
*a = *b;
*b = tmp;
}
int sort(char *s,int end)
{
int middle = (end)/2;
if((end)>=2){
sort(s,middle); //二分
sort(s+middle+1,end-middle-1);
int i=0,j=middle+1,k=0;
/*将两边数据按顺序放置于缓存*/
while(i<=middle && (j<=end)){
if(s[i]>s[j]){
copy[k] = s[j];
j++;
}else{
copy[k] = s[i];
i++;
}
k++;
}
while(i <= middle){
copy[k] = s[i];
i++;
k++;
}
while(j <= end){
copy[k] = s[j];
j++;
k++;
}
/*更新*/
for(k=0;k<=end;k++){
s[k] = copy[k];
}
}
else if((end) == 1)
if(s[0]>s[1]) swap(&s[0],&s[1]); //排序
}
int main(void)
{
char a[10]={1,2,5,7,8,4,3,6,9,0};
sort(a,sizeof(a)-1);
int i=0;
for(i=0;i<sizeof(a);i++)
printf("%4d",a[i]);
printf("\n");
return 0;
}
堆序法
堆序法其实就是一颗二叉树,父节点大于子节点。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void swap(char *a, char *b)
{
char tmp = *a;
*a = *b;
*b = tmp;
}
char tmp;
int heapsort(char *s,int index,int len)
{
index--;
tmp=s[index];
int son=0;
int father=index;
for(son=index*2+1;son<len;son=2*son+1){
tmp = s[father];
if(son<(len-1) && s[son]<s[son+1]) son++;
if(s[father]>s[son]) break;
s[father] = s[son];
father = son;
s[son]=tmp;
}
s[father]=tmp;
}
//char a[6]={4,3,6,5,1,2};
int main(void)
{
char a[10]={7,5,2,1,8,4,3,6,9,0};
int i=0;
for(i=0;i<sizeof(a);i++)
a[i]=random()%100;
int len=sizeof(a);
/*heap*/
for(i=len/2;i>0;i--)
heapsort(a,i,len);
/*sort*/
for(i=len-1; i>=1; i--) {
tmp = a[i];
a[i] = a[0];
a[0] = tmp;
heapsort(a,1,i);
}
for(i=0;i<len;i++)
printf("%3d",a[i]);
printf("\n");
return 0;
}
归并排序跟堆序法的时间复杂度都是O(lgn),但是堆序法的开销小,只要O(1),而归并排序需要O(n)