插入排序与归并排序及优化

看CLRS顺便做下笔记总结一下,理清思路。(所有排序例子皆为从小到大,各位觉得哪里能更好地改进都可以指出来)

插入排序(c语言实现)

最坏情况下的运行时间是Θ(n*n),跟冒泡排序,选择排序的最坏情况下的运行时间是相同的

但是,运算的速度 插入>选择(相比冒泡交换的次数较少)>冒泡

最简单的例子啦,打牌的时候一张一张的拿到手里插入排序。

上代码

#include<stdio.h>
#include<stdlib.h>
int main(void){
    int j,i,num,key;
    scanf("%d",&num);
    int *ptr;
    ptr=(int *)malloc(num*sizeof(int));//动态内存分配
    for(i=0;i<num;i++){
        scanf("%d",&ptr[i]);
    }
    for(i=1;i<num;i++){
        key=ptr[i];//你拿到的“牌”
        j=i-1;//通过迭代找到合适的位置,将其他牌向前推
        while(j>=0&&ptr[j]>key){
            ptr[j+1]=ptr[j];
            j-=1;
        }
        ptr[j+1]=key;//最后把牌放进去
    }
    for(i=0;i<num;i++){
        printf("%d ",ptr[i]);
    }
    free(ptr);
    return 0;
}

以上的方法是从迭代实现插入排序

那么我们试下递归实现插入排序

#include<stdio.h>
#include<stdlib.h>
void insert_sort(int *ptr,int num);
int main(void){
    int i,num,*ptr;
    scanf("%d",&num);
    ptr=(int *)malloc(num*sizeof(int));
    for(i=0;i<num;i++){
        scanf("%d",&ptr[i]);
    }
    insert_sort(ptr,num-1);
    for(i=0;i<num;i++){
        printf("%d ",ptr[i]);
    }
    free(ptr);
    return 0;
}


void insert_sort(int *ptr,int num){
    int j,i,key;
    static index=0;
    j=index+1;
    key=ptr[j];
    i=j-1;
    while(i>=0&&ptr[i]>key){
        ptr[i+1]=ptr[i];
        i--;
    }
    ptr[i+1]=key;
    index++;
    if(index<num){
        insert_sort(ptr,num);
    }
}

归并排序(c语言实现)

采用的是分治的思想Divide and Conquer

最坏情况下的运行时间是Θ(n*Ign),其中Ign相比任何的线性函数增长慢,所以归并排序的性能要优于插入排序。

归并排序就等于画树,其中树的每一层加起来都等于cn,树的高度一共是Ign层,merge的子程序耗费的时间是Θ(n)

一共加起来的时间就是cn*lgn+Θ(n),通过渐近符号得到最高项就是Θ(n*Ign)

上代码(这里的归并排序并没有采用哨兵的方法)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void merge_sort(int *ptr,int low,int high);
void merge(int *ptr,int leftlow,int lefthigh,int rightlow,int righthigh);
int main(void){
    int size,index;
    scanf("%d",&size);
    int *ptr;
    ptr=(int *)malloc(size*sizeof(int));
    for(index=0;index<size;index++){
        scanf("%d",&ptr[index]);
    }
    merge_sort(ptr,0,size-1);
    for(index=0;index<size;index++){
        printf("%d ",ptr[index]);
    }
    free(ptr);
    return 0;
}


void merge_sort(int *ptr,int low,int high){
    if(low<high){
        int middle;
        middle=low+(high-low)/2;
        merge_sort(ptr,low,middle);
        merge_sort(ptr,middle+1,high);
        merge(ptr,low,middle,middle+1,high);
    }
}


void merge(int *ptr,int leftlow,int lefthigh,int rightlow,int righthigh){
    int num;
    num=(lefthigh-leftlow+1)+(righthigh-rightlow+1);
    int *sort_array;
    int index=0;
    int leftindex=leftlow;
    int rightindex=rightlow;
    sort_array=(int *)malloc(num*sizeof(int));
    while(leftindex<=lefthigh&&rightindex<=righthigh){
        if(ptr[leftindex]<=ptr[rightindex]){
            sort_array[index++]=ptr[leftindex++];
        }
        else{
            sort_array[index++]=ptr[rightindex++];
        }
    }
    while(leftindex<=lefthigh){
        sort_array[index++]=ptr[leftindex++];
    }
    while(rightindex<=righthigh){
        sort_array[index++]=ptr[rightindex++];
    }
    memcpy(ptr+leftlow,sort_array,num*sizeof(int));
    free(sort_array);
}

那么,就如函数y=n*n与函数y’=n*n*n一样存在一个点,使得小于该点时y

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 30
void merge_sort(int *,int ,int );
void merge(int *,int ,int ,int ,int );
void insert_sort(int *,int ,int );
int main(void){
    int i,size,*ptr;
    scanf("%d",&size);
    ptr=(int *)malloc(size*sizeof(int));
    for(i=0;i<size;i++){
        scanf("%d",&ptr[i]);
    }
    merge_sort(ptr,0,size-1);
    for(i=0;i<size;i++){
        printf("%d ",ptr[i]);
    }
    free(ptr);
    return 0;
}


void merge_sort(int *ptr,int low,int high){
    if((high-low)<=MAX){
        insert_sort(ptr,low,high);
    }
    else if((high-low)>MAX){
        int mid;
        mid=low+(high-low)/2;
        merge_sort(ptr,low,mid);
        merge_sort(ptr,mid+1,high);
        merge(ptr,low,mid,mid+1,high);
    }
}


void insert_sort(int *ptr,int low,int high){
    int i,j;
    int key;
    for(j=low+1;j<=high;j++){
        key=ptr[j];
        i=j-1;
        while(i>=low&&ptr[i]>key){
            ptr[i+1]=ptr[i];
            i--;
        }
        ptr[i+1]=key;
    }
}


void merge(int *ptr,int leftlow,int lefthigh,int rightlow,int righthigh){
    int size;
    size=(lefthigh-leftlow)+1+(righthigh-rightlow)+1;
    int *sort_array;
    sort_array=(int *)malloc(size*sizeof(int));
    int index=0;
    int leftindex=leftlow;
    int rightindex=rightlow;
    while(leftindex<=lefthigh&&rightindex<=righthigh){
        if(ptr[leftindex]<ptr[rightindex]){
            sort_array[index++]=ptr[leftindex++];
        }
        else{
            sort_array[index++]=ptr[rightindex++];
        }
    }
    while(leftindex<=lefthigh){
        sort_array[index++]=ptr[leftindex++];
    }
    while(rightindex<=righthigh){
        sort_array[index++]=ptr[rightindex++];
    }
    memcpy(ptr+leftlow,sort_array,size*sizeof(int));
    free(sort_array);
}

你可能感兴趣的:(归并排序,插入排序,C语言)