C語言排序算法--快速排序

快速排序

1. 原理分析

  • 快速排序在日常編程中是比較常見的一種排序手段。它的實現相比較於冒泡排序來說可能複雜一些,因爲他用到了遞歸的思想,其實只要理解其排序的思想,我們會發現快速排序也沒有那麼難。

  • 在快速排序中,我們使用了分治法,簡言之就是分而治之。那麼根據什麼來分呢?

  • 這裏我們需要選取一個基準值,給他去個名字叫key吧。基準值我們一般選取數組的第一個元素的值:key = array[0] (當然了, 你可以選取數組中的任意一個值來作爲基準值)

    然後就是比較環節了,我們拿這個基準值去跟其他的每一值去比較,比基準值大的就放在它的右邊,比基準值小的就放在它的左邊。這樣原來的數組就別分成了基準值的做和右兩部分,然後左邊部分和右邊部分有按照這種辦法來繼續分區而治。這裏就體現了分治法的精髓。再深入思考一下,這個過程是不是很像遞歸的過程呢(二叉樹的遍歷過程也和這個很像的)。所以這裏也用到了遞歸的思想。

  • 口說無憑,下面來舉個例子。

    定義一個數組:int a[] = {33,12,8,46,5,88}

    1. 首先選取一個基準值key(一般選a[0]),key = a[0]

    2. 然後定義兩個下標(用來遍歷數組),i,j;分別用來表示數組的第一個元素的下標和最後一個元素的下標。i = 0,j = len-1;

    3. 33 12 8 46 5 88

      i------------------j

      開始移動時,j移動到5的位置,此時a[j] < a[i](不滿足的話執行j--,即j繼續向左移動,直到該條件滿足),前面我們已經將a[i]的值保存到key中了,即已經將a[i]的值挖出了,使a[i]=a[j],然後開始移動i,即i++,移動到12位置發現:
      46比33大,就將a[j]=a[i],以此比較。當i>=j時,第一輪比較停止,此時a[i]=key;

      [5 12 8] 33 [46 88]

      到此,原來的的數據被分成了兩組

      繼續遞歸對兩邊的繼續分組

      最終,的到正確的排序。

二、實現代碼講解

void quick_sort(int a[],int low,int high)
{
    int i = 0,j = o,key = 0;
    i = low;
    j = high;	
    key = a[low];	//根據用戶傳入的值選取基準值
    
    while(i < j)
    {
        //從j開始,找到比key小的數,放在i的位置
        while(i < j && a[j] >= key)
        {
            j--;
        }
        if(i < j)
        {
            a[i] = a[j];	//將比a[i]大的值放到a[i]位置
        }
        while(i < j && a[i] <= key)
        {
            i++;	//i開始向後查找比key大的值
        }
        if(i < j)
        {
            a[j] = a[i];
        }
    }
    //循環結束後,a[i]的值沒有變,將key放到a[i]
    a[i] = key;
    //對左右的搬去進行遞歸快排
    qiuck_sort(a,low,i-1);	//對左搬去進行塊排
    qiuck_sort(a,j+1,high);	//對右半區進行快排
}

三、總結

  • 快速排序中事件複雜度會根據數據的位置不同而有所不同,如選取的基準值在中間,這樣這種排序方法的空間複雜度最低爲O(nlogn),相反,若每次選取的基準值都是最大最小值的話,那麼其空間複雜度爲O(n^2),所以該算法是不穩定的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章