八种排序的比较

#include
#include
#include
#include

#define COUNT 100

void InsertSort(int *arr);
void BInsertSort(int * arr);
void ShellInsert(int * arr ,int dk);
void ShellSort(int *arr);
void BubbleSort(int * arr);
void QuickSort(int * arr,int low ,int high);
int FindPos(int *arr,int low ,int high);
void SelectSort(int * arr);
void HeadSort(int *arr);
void HeapAdjust(int *arr,int s,int m);
void CreatHeap(int *arr);
void MSort(int *R ,int * T ,int low, int high);
void Merge(int *R,int *T,int low,int mid ,int high);



int main(){

    int arr[COUNT];
    int buff[COUNT];
    srand(time(NULL));
    for(int i =0;i<COUNT;i++){
        arr[i] = rand();
    }
    int n ;
    printf("请输入排序方法序号\n");
    printf("1 直接插入排序\n");
    printf("2 折半插入排序\n");
    printf("3 希尔排序\n");
    printf("4 冒泡排序\n");
    printf("5 快速排序\n");
    printf("6 简单选择排序\n");
    printf("7 堆排序\n");
    printf("8 归并排序\n");



    while(scanf("%d",&n)!=EOF){

        switch(n){

        case 1: InsertSort(arr);break;

        case 2: BInsertSort(arr);break;

        case 3: ShellSort(arr);break;

        case 4: BubbleSort(arr);break;

        case 5: QuickSort(arr,0,COUNT-1);break;

        case 6: SelectSort(arr);break;

        case 7: HeadSort(arr);break;

        case 8: MSort(arr,buff,0,COUNT-1);break;

        default: printf("输入错误,请重新输入:\n");

        }
        for(int i =0 ;i<COUNT;i++){
        printf("%d\n",arr[i]);

    }
        for(int i =0;i<COUNT;i++){
        arr[i] = rand();
    }

    }



    return 0;

}

//插入排序  之  直接插入排序
	/*
	 * 时间复杂度;O(n^2)
	 * 空间复杂度:O(1)
	 * 算法特点:
	 * 1.稳定排序
	 * 2.算法简便,且容易实现
	 * 3.也适用于链式存储结构,知识在单链表上无需移动记录,只需要修改相应的指针
	 * 4.更适用于初始记录基本有序的情况,当初是记录无序,n较大时,此算法时间复杂度较高,不宜采用。
	 */
void InsertSort(int *arr){
    for(int i = 1,val=0,j;i<COUNT;i++){
        if(i<COUNT&&arr[i]<arr[i-1]){
            val = arr[i];
            arr[i]=arr[i-1];
            for( j =i-2;j>=0&&arr[j]>val;j--){
                arr[j+1]=arr[j];
            }
            arr[j+1] = val;
        }

    }

}

//插入排序之  折半插入排序
	/*
	 * 时间复杂度;O(n^2)
	 * 空间复杂度:O(1)
	 * 算法特点:
	 * 1.稳定排序
	 * 2.因为要进行折半查找,所以只能用于顺序结构,不能用于链式结构
	 * 3.适合初始记录无序,n较大时的情况。
	 */
void BInsertSort(int * arr){

      for(int i =1 ; i < COUNT;i++){

            if(arr[i]<arr[i-1]){
                int val = arr[i];
                int low = 0;
                int high = i-1;
                while(low<=high){
                    int mid = (low+high)/2;
                    if(arr[mid]<val){
                        low = mid+1;
                    }else{

                        high = mid-1;
                    }
                }
                for(int j = i-1;j>=high+1;j--){
                    arr[j+1]=arr[j];
                }
                arr[high+1] = val;

            }

      }
}

//插入排序之  希尔排序
	/*
	 * 时间复杂度;O(n^(3/2))
	 * 空间复杂度:O(1)
	 * 算法特点:
	 * 1.记录跳跃式的移动导致排序方法是不稳定的
	 * 2.只能用于顺序结构,不能用于链式结构
	 * 3.增量序列可以使用各种取法,当应该使增量序列中的值没有除1之外的公因子,并且最后的一个增量必须等于1
	 * 4.记录总的比较次数和移动次数都比直接插入排序要少,n越大时,效果越明显,所以适合记录无序,n较大时的情况
	 *
	 */
void ShellInsert(int * arr ,int dk){
    for(int i =dk,j ;i<COUNT;i++){
        if(arr[i]<arr[i-dk]){

            int val = arr[i];
            for( j = i-dk;j>=0&&arr[j]>val;j-=dk){

                    arr[j+dk]=arr[j];

            }
            arr[j+dk] = val;
        }
    }
}

void ShellSort(int * arr){
     int dt[10] = {1000,300,200,99,70,44,19,9,4,1};
     for(int i =0 ;i<10;i++){
        ShellInsert(arr,dt[i]);
     }
}


//	交换排序 之 冒泡排序
	/*
	 * 时间复杂度;O(n^2)
	 * 空间复杂度:O(1)
	 * 算法特点:
	 * 1.稳定排序
	 * 2.可适用链式存储结构。
	 * 3.移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时,此算法不宜采用。
	 */
void BubbleSort(int * arr){
    int flag = 1;
    for(int i = 1 ;i< COUNT&&flag == 1;i++){
            flag = 0;
        for(int j =0 ;j< COUNT - i;j++){
            if(arr[j]>arr[j+1]){
                flag = 1;
                arr[j] = arr[j]^arr[j+1];
                arr[j+1] = arr[j]^arr[j+1];
                arr[j] = arr[j]^arr[j+1];
            }
        }
    }
}

//   交换排序之  快速排序
	/*
	 * 时间复杂度;O(nlog2(n)).
	 * 空间复杂度;最好的情况是:O(log2(n)),最坏的情况是:O(n).
	 * 算法特点:
	 * 1.记录非顺次的移动导致排序方法是不稳定的。
	 * 2.排序过程中需要定位表的上界和下届,所以适合用于顺序结构,很难用于链式储存结构
	 * 3.当n较大时,在平均情况下快速排序是在所有内部排序方法中速度最快的一种,所以其适合初始记录无序,n较大时的情况。
	 */

int FindPos(int * arr ,int low ,int high){
    int val = arr[low];
    while(low<high){
            while(low<high&&arr[high]>=val){
                high--;
            }
            arr[low] = arr[high];
            while(low<high&&arr[low]<=val){
                low++;
            }
            arr[high] = arr[low];
    }
    arr[low] = val;
    return low;

}

void QuickSort(int * arr,int low ,int high){
    if(low<high){
        int pos = FindPos(arr,low,high);
        QuickSort(arr,low,pos-1);
        QuickSort(arr,pos+1,high);
    }

}
// 选择排序之  简单选择排序
	/*
	 * 时间复杂度;O(n^2)
	 * 空间复杂度:O(1)
	 * 算法特点:
	 * 1.稳定排序
	 * 2.可用于链式储存结构
	 * 3.移动记录次数较少。此方法比直接插入排序快。
	 */

void SelectSort(int * arr){
    for(int i =0;i<COUNT -1;i++){
        int k = i;
        for(int j = i+1;j<COUNT;j++){
            if(arr[k]>arr[j]){
                k = j;
            }
        }
        if(k!=i){
            arr[i] = arr[i]^arr[k];
            arr[k] = arr[i]^arr[k];
            arr[i] = arr[i]^arr[k];
        }
    }
}


// 选择排序之 堆排序
	/*
	 * 实验研究表名:平均性能接近最坏性能
	 * 堆排序在最坏的情况下,其
	 * 时间复杂度:O(nlog2(n))
	 * 空间复杂度:O(1)
	 * 算法特点:
	 * 1.是不稳定排序。
	 * 2.只能用于顺序结构,不能用于链式结构
	 * 3.初始建对所需的比较次数较多 ,因此记录数较少时不宜采用。
	 * 堆排序在最坏的情况下时间复杂度为O(nlog2(n)),相对于快速排序最坏情况下的O(n^2)而言是一个优点,当记录较多时较为高效。
	 */
/**
    堆排序
    1.筛选法求大根堆
    2.构建堆
    3.对堆进行排序
*/

void HeapAdjust(int * arr,int s,int m){

    int j = 0;
    int val = arr[s];
    for(int j= 2*s;j<=m;j*=2){
        if(j<m&&arr[j]<arr[j+1]){
            j++;
        }
        if(val>=arr[j])
            break;
        arr[s] = arr[j];
        s=j;
    }
    arr[s]= val;
}

void CreatHeap(int *arr){

    for(int j =COUNT/2;j>=0;j--){
        HeapAdjust(arr,j,COUNT-1);
    }
}

void HeadSort(int *arr){
    CreatHeap(arr);
    for(int i = COUNT-1;i>=1;i--){
        arr[i] = arr[i]^arr[0];
        arr[0] = arr[i]^arr[0];
        arr[i] = arr[i]^arr[0];
        HeapAdjust(arr,0,i-1);
    }
}

//归并排序
	/*
	 * 时间复杂度:O(nlog2(n))
	 * 空间复杂度:O(n)
	 * 算法特点:
	 * 1.是稳定排序
	 * 2.可用于链式结构,且不需要附加存储空间,但是递归实现仍需要开辟相应的递归工作栈
	 */
void Merge(int *R ,int *T,int low ,int mid,int high){
    int i = low;
    int j = mid+1;
    int k = 0;
    while(i<=mid&&j<=high){
        if(R[i]<R[j]){
            T[k++] = R[i++];
        }else{
            T[k++] = R[j++];
        }
    }
    while(i<=mid){
        T[k++] = R[i++];
    }
    while(j<=high){
        T[k++] = R[j++];
    }

    for(int t = 0;t<k;t++){
        R[low+t] = T[t];
    }
}

void MSort(int *R ,int * T ,int low, int high){

    if(low<high){
        int mid =(low+high)/2;
        MSort(R,T,low,mid);
        MSort(R,T,mid+1,high);
        Merge(R,T,low,mid,high);
    }

}












你可能感兴趣的:(C语言)