快速排序

#include <stdio.h>
#include <stdlib.h>
#include<assert.h>
#include<time.h>

//count用來記錄次數
int  count1 = 0;
int count2 = 0;



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

int  Parition(int *arr, int low,int high)
{
    int  tmp = arr[low];//拿出單獨的一個基準
    while (low < high)
    {
        while (arr[high] >= tmp && low <high)//添加等於可進行相同數字的處理
        {
            count1++;
            high--;
        }
        arr[low]=arr[high];
        while (arr[low] <= tmp && low < high)
        {
            count1++;
            low++;
        }
        arr[high]=arr[low];//low == high或者arr[low]>tmp才執行這句
    }
    arr[low] = tmp;
    return low;
}
void Quick(int *arr, int low, int high)
{
    if (low < high)
    {
        int part = Parition(arr, low, high);
        Quick(arr, low, part - 1);
        Quick(arr, part + 1, high);
    }

}
//快速排序 找到中間分割點,再遞歸
void QuickSort(int *arr,int len)
{
    if (arr == NULL)return;
    Quick(arr,0,len-1);
}
//快速排序非遞歸
void Sort_Quick(int *arr, int len)
{
    if (arr == NULL) return;
    int *stack = (int *)malloc(sizeof(int)*len);
    assert(stack != NULL);
    int low = 0;
    int top = 0;
    int high = 0;
    int Part = 0;

    stack[top++] = 0;
    stack[top++] = len - 1;
    while (top != 0)//棧不爲空
    {
        high=stack[--top];
        low = stack[--top];
        Part = Parition(arr,low,high);//反覆利用該函數排序找一下中間值
        if (low < Part-1)//左邊入棧
        {  
            count2++;
            stack[top++]=low;
            stack[top++]=Part-1;
        }
        if (Part+1 < high)//右邊入棧
        {
            count2++;
            stack[top++] = Part+1;
            stack[top++] = high;
        }
    }
    free(stack);//釋放申請的額外空間
}


int main()
{
    int arr1[] = {11,3,15,10,7,2,44,1,0};
    int n1 = sizeof(arr1) / sizeof(sizeof(arr1[0]));

    printf("快速排序(遞歸):\n");
    QuickSort(arr1,n1);
    Show(arr1, n1);
    printf("執行次數:%d\n",count1);


    int arr2[] = { 11, 3, 15, 10, 7, 2, 44, 1, 0 };
    int n2 = sizeof(arr2) / sizeof(sizeof(arr2[0]));

    printf("快速排序(非遞歸):\n");
    Sort_Quick(arr2, n2);
    Show(arr2, n2);
    printf("執行次數:%d\n", count2);
    return 0;

}

運行結果:
這裏寫圖片描述

快速排序的時間複雜度:

最壞情況是每次劃分選取的基準都是當前無序區中關鍵字最小(或最大)的記錄,劃分的結果是基準左邊的子區間爲空(或右邊的子區間爲空),而劃分所得的另一個非空的子區間中記錄數目,僅僅比劃分前的無序區中記錄個數減少一個。時間複雜度爲O(n*n)

最好情況是每次劃分所取的基準都是當前無序區的”中值”記錄,劃分的結果是基準的左、右兩個無序子區間的長度大致相等。總的關鍵字比較次數:O(nlgn)

儘管快速排序的最壞時間爲O(n2),但就平均性能而言,它是基於關鍵字比較的內部排序算法中速度最快者。它的平均時間複雜度爲O(nlgn)。

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