C之插入排序

研後重新學習數據結構。
#include<stdio.h>
typedef int ElemType;
void InsertSort(ElemType A[],int n);
void BInsertSort(ElemType A[],int n);
void ShellSort(ElemType A[],int n);
void print_arr(ElemType A[],int n);
int  main()
{
    int Arr[9] = {0,5,2,68,676,3,46,74,32};
    int Arr_num = 8;
     printf("原數組: ");
    print_arr(Arr,Arr_num);

//    printf("---直接插入排序---\n");
//    InsertSort(Arr,Arr_num);
//    print_arr(Arr,Arr_num);
//
//    printf("---二分查找插入排序---\n");
//    BInsertSort(Arr,Arr_num);
//    print_arr(Arr,Arr_num);

    printf("---希爾排序---\n");
    ShellSort(Arr,Arr_num);
    print_arr(Arr,Arr_num);

    return 0;
}

//直接插入
//將子序列按照順序一個個排序好,不斷向已經排序好的子序列中插入元素
//穩定
//時間複雜度n~n^2
//空間複雜度1
//比較和移動次數都與初始狀態相關
//比較最好爲n-1,最壞爲n(n-1)/2,平均比較n^2/4
//移動最好爲0,最壞爲n(n+1)/2,平均移動n^2/4

void InsertSort(ElemType A[],int n)
{
    int i,j;
    for( i = 2; i <= n; i ++)
    {
        if( A[i] < A[i-1] )
        {
            A[0] = A[i];
            for( j = i - 1; j > 0&&A[0] < A[j]; j --)//第一個條件可以不用 j按一個長度遞減,數組不會越界
                A[j + 1] = A[j];
            A[j + 1] = A[0];
        }
    }

}

//折半插入
//直接插入的變形 在已排序好的子序列中查找待插入元素的位置,使用二分查找
//穩定
//時間複雜度 n*log2(n)~n^2
//比較次數與初始狀態無關,始終爲n*log2(n)
//移動次數與初始狀態相關,順序爲0,逆序爲n(n+1)/2,平均移動n^2/4
void BInsertSort(ElemType A[],int n)
{
    int i,j,low,high,mid;
    for(i = 2; i <=n; i ++)
    {
        low = 0;
        high = n - 1;
        A[0] = A[i];
        while(low <= high)
        {
            mid = (low + high) /2;
            if(A[mid] > A[0]) high = mid - 1;
            else low = mid + 1;
        }
        for(j = i - 1; j >= high + 1; j --)
        {
            A[j + 1] = A[j];
        }
        A[high + 1] = A[0];
    }
}

//希爾
//對排序表進行按照 i,i+dk,i+2dk···進行分割,然後進行直接插入排序
//直接插入排序是步長都爲1
//不穩定 複雜度n^1.3~n^2
void ShellSort(ElemType A[],int n)
{
    int dk;//步長
    int  count = 0;//排序次數
    int i,j;
    for(dk = n/2; dk >= 1; dk = dk/2)
    {
        ++ count;
        for(i = 1 + dk; i <= n; i ++)
        {

            if(A[i] < A[i - dk])
            {
                A[0] = A[i];
                for(j = i - dk; j > 0 && A[0] < A[j]; j -= dk)//j>0邊界條件不可省略 j - dk可能大於小於0,數組越界
                    A[j + dk] = A[j];
                A[j + dk] = A[0];
            }
        }
        printf("第%d次排序: ",count);
        print_arr(A,n);//打印每次排序結果
    }
}

void print_arr(ElemType A[],int n)
{
    int i;
    for(i = 1; i <= n; i++)
    {
        printf("%d ",A[i]);
    }
    printf("\n");
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章