10大經典排序算法-已經親自驗證

10大經典排序

參考書籍--王道-數據結構第8章節--算法代碼在Visio Stdio 2019驗證過!

根據操作方式可分5類:插入排序,交換排序,選擇排序,歸併和基數排序
    其中:
        插入排序:直接插入,折半插入,希爾排序(3)
        交換排序:冒泡,快速排序;(2)
        選擇排序:簡單選擇、堆排序;(2)
        歸併排序
        基數排序--不提供比較

算法認識

動態圖--參考地址:https://www.cnblogs.com/onepixel/p/7674659.html

性能比較:
image

測試代碼

// 10大經典排序.cpp -除基數排列外其他已驗證
//edit by justin in the visio stdio 2019
#define len 10
#include <iostream>
/*1 插入排序-1-直接插入排序 */
void InsertionSort(int A[],int n)
{
    int i,j;
    int buff;//緩存哨兵
    for(i = 1;  i < n;i++)
    {
        if (A[i] < A[i - 1])
        {
            buff = A[i];
            for (j = i - 1; A[j]>buff; --j)
               A[j+1] = A[j];
            A[j +1] = buff;
        }
    }
}

//2-折半插入排序法
void Bin_InserSort(int A[], int n)
{
    int i, j, low, high, mid,buff_a;
    for (i = 1; i < n; i++)
    {
        buff_a = A[i];//哨兵
        //在0~(i-1)實現折半查找插入位置
        low = 0, high = i - 1;
        while (low <= high)
        {
            mid = (low + high) / 2;
            if (A[mid] >= buff_a)
                high = mid - 1;
            else
                low = mid + 1;
        }
        //移動位置
        for (j = i; j >low; j--)
            A[j] = A[j-1];
        //插入
        A[low] = buff_a;
    }
}
//3-希爾排序
void ShellSort(int A[], int n)
{
    int i, j;
    int buff_a;//緩存
    for (int dk =n/2 ; dk >= 1; dk=dk/2)
    {
        for (i = dk ; i < n; i++)
        {
            if (A[i] < A[i - dk])
            {
                buff_a = A[i];
                for (j = i - dk; j>0&&j < n; j=j-dk)
                    A[j + dk] = A[j];
                A[j + dk] = buff_a;
            }
        }
    }
}
void swap(int *a, int *b)
{
    int tmp=*a;
    *a = *b;
    *b=tmp;
}
//4 交換排序1--冒泡排序
void bubbleSort(int A[], int n)
{
    int i, j;
    int flag;//緩存
    for (i = 0; i < n-1; i++)
    {
        flag = false;
        for (j = n - 1; j > i; j--)
        {
            if (A[j] < A[j - 1])
            {
                swap(&A[j], &A[j-1]);
                flag = true;
            }
        }
        if (flag == false)
            return;
    }
}
//5 交換排序2-快速排序
int Partition(int A[], int low,int high)
{
    int pivot = A[low];//軸點元素
    while (low<high)
    {
        if (low<high && A[high]>pivot) --high;
        A[low] = A[high];
        if (low < high && A[low] < pivot) ++low;
        A[high]=A[low];
    }
    A[low] = pivot;
    return low;
}
void QuickSort(int A[], int low, int high)
{
    if (low < high)
    {
        int pivotpos = Partition(A,low,high);
        QuickSort(A,low,pivotpos-1);
        QuickSort(A,pivotpos+1,high);
    }
}
//6 簡單選擇排序
void SimpleSelectSort(int A[], int n)
{
    int i, j, buff_min;
    for (i = 0; i < n; i++)
    {
        buff_min = i;
        for (j = i+1; j < n; j++)
        {
            if (A[j] < A[buff_min]) buff_min = j;
        }
        if (buff_min != i)
            swap(&A[buff_min],&A[i]);
    }
}
//7 堆排序
void AdjustDown(int A[], int i, int n)
{//將元素k向下調整
    int parent = i;//k=4,3,2,1,0
    int child = 2 * i + 1;
    while (child < n) {
        if (A[child] < A[child + 1] && child + 1 < n) {	//判斷子節點那個大,大的與父節點比較 
            child++;
        }

        if (A[parent] < A[child]) {				//判斷父節點是否小於子節點 
            swap(&A[parent], &A[child]);					//交換父節點和子節點 
            parent = child;								//子節點下標 賦給 父節點下標 
        }

        child = child * 2 + 1;								//換行,比較下面的父節點和子節點 
    }
}
//9 堆排序
void BuildMaxHeap(int A[], int n)
{
    for (int i = n / 2-1; i >= 0; i--)
    {
        AdjustDown(A,i, n);//反覆調整
    }
}
void HeapSort(int A[], int n)
{
    int i;
    BuildMaxHeap(A,n);//初始建大根堆
    printf("\n初始化大根堆的數組:");
    for (int i = 0; i < n; i++)  printf("%d ", A[i]);
    printf("\n");
    
    for (i = n-1; i > 0; i--)//排序
    {
        swap(&A[i],&A[0]);
        AdjustDown(A,0,i);
        printf("排序的數組過程%d:",i+1);
        for (int i = 0; i < n; i++)   printf("%d ", A[i]);
        printf("\n");
    }
}
//9 歸併排序
int* B = (int*)malloc((len + 1) * sizeof(int));
void Merge(int A[], int low,int mid, int high)
{
    int i, j, k;
    for ( k = low; k <= high; k++)
        B[k] = A[k];
    for ( i = low, j = mid+1 , k = i; i <= mid && j <= high; k++)
        if (B[i] < B[j]) A[k] = B[i++];
        else A[k] = B[j++];
    while (i < mid) A[k++] = B[i++];
    while (j < high) A[k++] = B[j++];

}
void MergeSort(int A[],int low,int high)
{
    if (low < high)
    {
        int mid = (low + high) / 2;
        MergeSort(A,low,mid);
        MergeSort(A,mid+1,high);
        Merge(A,low,mid,high);
    }
}
//10 基數排序-暫無

int main()
{
    std::cout << "Hello World!\n";
    int arr[len] = { 11,5,1,-7,4,9,-6,8,10,15 };
    printf("測試原始數據:");
    for (int i = 0; i < len; i++)
        printf("%d ", arr[i]);
    
    //printf("\n插入排序1-插入排序結果:");
    //InsertionSort(arr,len);
    //printf("\n插入排序2-折半插入排序結果:");
    //Bin_InserSort(arr, len);
    //printf("\n插入排序3-希爾插入排序結果:");
    //ShellSort(arr, len);
    //printf("\n插入排序2-折半插入排序結果:");
    //InsertionSort(arr,len);
    //printf("\n交換排序1-冒泡排序結果:");
    //bubbleSort(arr, len);
    //printf("\n交換排序2-快速排序結果:");
    //QuickSort(arr, 0,len-1);
    //printf("\n選擇排序1-簡單選擇排序結果:");
    //SimpleSelectSort(arr, len); 

    HeapSort(arr, len);
    printf("\n選擇排序2-堆排序結果:");
    //printf("\n歸併排序-歸併序結果:");
    //MergeSort(arr, 0,len-1);
    //printf("\n基數排序-基數序結果:");
    //BaseSort(arr, len);
    for (int i = 0; i < len; i++)
        printf("%d ", arr[i]);

    return 0;
}

 

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