排序演算法 二 快速,歸併,堆排序

2021-08-08 11:08:41 字數 2262 閱讀 8531

快速排序

快速排序使用分治策略(divide and conquer)來把乙個序列分為兩個子串行。

步驟為:

1.從序列中挑出乙個元素,作為」基準」(pivot).

2.把所有比基準值小的元素放在基準前面,所有比基準值大的元素放在基準的後面(相同的數可以到任一邊),這個稱為分割槽(partition)操作。

3.對每個分割槽遞迴地進行步驟1~2,遞迴的結束條件是序列的大小是0或1,這時整體已經被排好序了。

舉個栗子:對5,3,8,6,4這個無序序列進行快速排序,思路是右指標找比基準數小的,左指標找比基準數大的,交換之。

5,3,8,6,4 用5作為比較的基準,最終會把5小的移動到5的左邊,比5大的移動到5的右邊。

5,3,8,6,4 首先設定i,j兩個指標分別指向兩端,j指標先掃瞄(思考一下為什麼?)4比5小停止。然後i掃瞄,8比5大停止。交換i,j位置。

5,3,4,6,8 然後j指標再掃瞄,這時j掃瞄4時兩指標相遇。停止。然後交換4和基準數。

4,3,5,6,8 一次劃分後達到了左邊比5小,右邊比5大的目的。之後對左右子串行遞迴排序,最終得到有序序列。

上面留下來了乙個問題為什麼一定要j指標先動呢?首先這也不是絕對的,這取決於基準數的位置,因為在最後兩個指標相遇的時候,要交換基準數到相遇的位置。一般選取第乙個數作為基準數,那麼就是在左邊,所以最後相遇的數要和基準數交換,那麼相遇的數一定要比基準數小。所以j指標先移動才能先找到比基準數小的數。

快速排序是不穩定的,其時間平均時間複雜度是o(nlgn)。

public

static

void

quicksort(int arr, int left, int right)

public

static

void

sort(int arr)

歸併排序

歸併排序的實現分為遞迴實現與非遞迴(迭代)實現。遞迴實現的歸併排序是演算法設計中分治策略的典型應用,我們將乙個大問題分割成小問題分別解決,然後用所有小問題的答案來解決整個大問題。非遞迴(迭代)實現的歸併排序首先進行是兩兩歸併,然後四四歸併,然後是八八歸併,一直下去直到歸併了整個陣列。

歸併排序演算法主要依賴歸併(merge)操作。歸併操作指的是將兩個已經排序的序列合併成乙個序列的操作,歸併操作步驟如下:

歸併演算法的基本步驟如下所示:

1)把0~length-1的陣列分成左陣列和右陣列

2)對左陣列和右陣列進行迭代排序

3)將左陣列和右陣列進行合併,那麼生成的整個陣列就是有序的資料陣列

void merge(int a, int left, int mid, int right)// 合併兩個已排好序的陣列a[left...mid]和a[mid+1...right]

while (i <= mid)

while (j <= right)

for (int k = 0; k < len; k++)

}void mergesortrecursion(int a, int left, int right) // 遞迴實現的歸併排序(自頂向下)

void mergesortiteration(int a, int len) // 非遞迴(迭代)實現的歸併排序(自底向上)

}}

堆排序

堆排序是指利用堆這種資料結構所設計的一種選擇排序演算法。堆是一種近似完全二叉樹的結構(通常堆是通過一維陣列來實現的),並滿足性質:以最大堆(也叫大根堆、大頂堆)為例,其中父結點的值總是大於它的孩子節點。

我們可以很容易的定義堆排序的過程:

1.由輸入的無序陣列構造乙個最大堆,作為初始的無序區

2.把堆頂元素(最大值)和堆尾元素互換

3.把堆(無序區)的尺寸縮小1,並呼叫heapify(a, 0)從新的堆頂元素開始進行堆調整

4.重複步驟2,直到堆的尺寸為1

void heapify(int a, int i, int

size) // 從a[i]向下進行堆調整

}int buildheap(int a, int n) // 建堆,時間複雜度o(n)

void heapsort(int a, int n)

}

參考部落格:

c排序演算法 選擇 冒泡 插入 快速 歸併 堆排序

1.選擇排序法 includeint main int n 5,i,k,b,x for b 0 b 4 b printf n for i 0 i n 1 i for b 0 b 4 b printf n return 0 2.氣泡排序法 includeint main int n 5,i,k,b,x...

演算法排序 快速排序,堆排序,歸併排序

31.快速排序 是對氣泡排序的一種改進,其基本思想是選取乙個記錄作為樞軸,經過一趟排序,將整段序列劃分為兩個部分,其中一部分的值都小於樞軸,另一部分都大於樞軸,然後繼續對這兩部分進行排序,從而使整個序列達到有序。1 我們從待排序的記錄序列中選取乙個記錄 通常第乙個 作為基準元素 稱為key key ...

歸併,快速,堆排序

堆排序 堆排序利用了大根堆 或小根堆 堆頂記錄的關鍵字最大 或最小 這一特徵,使得在當前無序區中選取最大 或最小 關鍵字的記錄變得簡單。1 用大根堆排序的基本思想 先將初始檔案r 1.n 建成乙個大根堆,此堆為初始的無序區 再將關鍵字最大的記錄r 1 即堆頂 和無序區的最後乙個記錄r n 交換,由此...