演算法導論 第7章 快速排序

2021-06-01 18:43:15 字數 2826 閱讀 5454

一、快速排序演算法的基本特性

時間複雜度:o(n*lgn)

最壞:o(n^2)

空間複雜度:o(n*lgn)

不穩定。

快速排序是一種排序演算法,對包含n個數的輸入陣列,平均時間為o(nlgn),最壞情況是o(n^2)。

通常是用於排序的最佳選擇。因為,排序最快,也只能達到o(nlgn)。

二、快速排序演算法的描述

演算法導論,第7章

快速排序時基於分治模式處理的,

對乙個典型子陣列a[p...r]排序的分治過程為三個步驟:

1.分解:

a[p..r]被劃分為倆個(可能空)的子陣列a[p ..q-1]和a[q+1 ..r],使得

a[p ..q-1] <= a[q] <= a[q+1 ..r]

2.解決:通過遞迴呼叫快速排序,對子陣列a[p ..q-1]和a[q+1 ..r]排序。

3.合併。

三、快速排序演算法

快速排序演算法的關鍵是partition過程,它對a[p..r]進行就地重排:

partition(a, p, r)

1  x ← a[r]         //以最後乙個元素,a[r]為主元

2  i ← p - 1

3  for j ← p to r - 1    //注,j從p指向的是r-1,不是r。

4       do if a[j] ≤ x

5             then i ← i + 1

6                  exchange a[i] a[j]

7  exchange a[i + 1] a[r]    //最後,交換主元

8  return i + 1

然後,對整個陣列進行遞迴排序:

quicksort(a, p, r)

1 if p < r

2    then q ← partition(a, p, r)   //關鍵

3         quicksort(a, p, q - 1)

4         quicksort(a, q + 1, r)

四、**

#include void swap(int *a, int *b);

void print(int* data, int len);

int partition(int* data, int lo, int hi)

} swap(&data[i+1], &data[hi]);

return i + 1;

}void quicksort(int data, int lo, int hi)

return;

}void main()

; print(arr, 11);

quicksort(arr, 0, 10);

print(arr, 11);

}void swap(int *a, int *b)

void print(int* data, int len)

printf("\n");

}

五、拓展

問題描述:

我們將亂序的紅白藍三色小球排列成有序的紅白藍三色的同顏色在一起的小球組。這個問題之所以叫荷蘭國旗,是因為我們可以將紅白藍三色小球想象成條狀物,有序排列後正好組成荷蘭國旗。如下圖所示:

這個問題,類似快排中partition過程。不過,要用三個指標,一前begin,一中current,一后end,倆倆交換。

1、current遍歷,整個陣列序列,current++,

2、current指0,與begin交換,而後current++,begin++,

3、current指2,與end交換,而後,current不動,end--。

為什麼,第三步,current指2,與end交換之後,current不動了列,對的,正如algorithm__所說:current之所以與begin交換後,current++、begin++,是因為此無後顧之憂。而current與end交換後,current不動,end--,是因有後顧之憂。

為什麼啊,因為你想想啊,你最終的目的無非就是為了讓0、1、2有序排列,試想,如果第三步,current與end交換之前,萬一end之前指的是0,而current交換之後,current此刻指的是0了,此時,current能動麼?不能動啊,指的是0,還得與begin交換列。

ok,說這麼多,你可能不甚明了,直接引用下gnuhpc的圖,就一目了然了:

本程式**:

#include void swap(int *a, int *b);

void print(int* data, int len);

void main()

; /* 初始化 begin, current, end */

int *begin = arr;

int *current = arr;

int *end = arr + 9;

/* 排序前,列印陣列 */

print(arr, 10);

/* current 遍歷整個陣列 */

while (current <= end)

/* current指向1,current ++ */

else if (1 == * current)

/* current指2,與end交換,而後,current不動,end-- */

else

}/* 排序後,列印陣列 */

print(arr, 10);

}void swap(int *a, int *b)

void print(int* data, int len)

printf("\n");

}

演算法導論 第7章快速排序

1 演算法描述 快速排序也是基於分治模式的,下面是乙個典型子陣列a p.r 排序的分治過程,主要分為三個步驟 1 分解 將陣列a p.r 劃分成兩個子陣列a p.q 1 和a q 1.r 使得前乙個陣列中每個值都小於等於a q 後乙個陣列每個值都大於a q 下標q也在這個分解過程中求得。2 解決 通...

《演算法導論》筆記 第7章 快速排序

第7章 快速排序 像合併排序一樣,快速排序也是基於分治模式的。下面對乙個典型的子陣列a p r 排序的分治過程的三個步驟 分解 陣列a p r 被劃分成兩個 可能空 的子陣列a p q 1 和a q 1 r 使得a p q 1 中的每個元素都小於等於a q a q 1 r 中的每個元素都大於等於a ...

《演算法導論》筆記 第7章 7 4快速排序分析

利用randomized partition,快速排序演算法期望的執行時間當元素值不同時,為o nlgn 7.4 1 證明 在遞迴式 中,t n n 2 採用代換法。猜測 t n c n 2,c為某個常數。選擇足夠大的c,使得 c 2 n 1 可以支配 n t n c n 2成立。7.4 2 證明 ...