數據結構與算法分析 - 快速排序

大二其實已經學習過了快排,可是如今基本上已經忘記了快排的細節和具體實現。如今爲了準備可能的面試,從新複習一下快速排序。溫故知新,古人誠不欺我。主要以《算法導論》爲教材。面試

《算法導論》這本書在介紹算法時,首先給出算法的描述,也就是僞碼,而後就是算法的正確性證實和優化。本文首先也是給出算法的僞碼,至於正確性的證實,仍是看本身可否勝任。算法

快排的大體框架

QUICKSORT(A,p,r)
if p < r
    then q = PARTITION(A,p,r)
    QUICKSORT(A,p,q-1)
    QUICKSORT(A,q+1,r)

 瞭解快排,就會知道快排的核心思想就是每次實現這樣一個數組:選定數組中某一個值,確保該值左邊的元素都比它小,右邊的元素都比它大。這樣雖然不能保證改值左邊和右邊的元素必定是有序的,可是必定可以保證該值在排序後的數組中的相對位置不會改變。好比說A[i]此時在第i個位置,當整個數組排完序以後,A[i]必定仍是在i。這樣也就知道爲何上面代碼中遞歸的時候不用包含q的值,由於它的位置已經肯定了。數組

通過以上的分析,就不難在實際編碼中寫出快排的大體框架了。框架

快排的劃分

顯而易見,快排採用的是分治的思想。每次將一個任務分爲兩個或者多個部分來解決。可是如何劃分其實才是快排的難點和重點。在面試的工程中被問道了這個問題,本身徹底忘了如何劃分。學習

若是要保證每次排序後的數組都知足左邊的都比指定元素要小,右邊則都要大,必需要選擇一個參照值做爲比較的對象,這個參考值就叫作主元。肯定了組員,就開始遍歷比較。優化

假設每次選取的都是最右邊的元素做爲主元,那麼就能夠從左到右來比較和肯定元素的位置。具體見下面的僞碼。ui

PARTITION(A,p,r)
x = A[r]
i = p - 1
for j : p to r
    do if A[j] < x
            then i = i + 1
            exchange(A[i],A[j])
exchange(A[i+1],A[r])
return i+1

大體的策略就是儘可能讓比主元小的元素排在前面。就這樣,很神奇的整個數組就排完序了。編碼

C代碼實現

/*************************************************************************
    > File Name: myfiles/C/sort/quicksort.c
    > Author: ma6174
    > Mail: ma6174@163.com 
    > Created Time: 2014年10月06日 星期一 11時38分28秒
 ************************************************************************/

#include<stdio.h>
#define maxn 100
int A[maxn];
int n;
/* 輸入數據 */
void read()
{
	printf("input the num:\n");
	scanf("%d",&n);
	int i;
	for(i = 0; i < n; i++) {
		scanf("%d",&A[i]);
	}
}
/* 分治 */
int partition(int A[], int p, int r)
{
	int key = A[r];
	int i = p - 1;
	int j;
	for(j = p; j < r; j++) {
		if(A[j] < key) { /* 目前爲止,沒有等於好也能夠正確執行,可是我不肯定要不要等號*/
			i++;
			int temp = A[i];
			A[i] = A[j];
			A[j] = temp;
		}
	}
	int temp = A[i+1];
	A[i+1] = key;
	A[r] = temp;
	return i+1;
}
/* 快排 */
void quick_sort(int A[], int p, int r)
{
	if(p < r) {
		int q = partition(A,p,r);
		quick_sort(A,p,q-1);
		quick_sort(A,q+1,r);
	}
}
/* 輸出 */
void write() 
{
	printf("the sorted array:\n");
	int i;
	for(i = 0; i < n; i++) {
		printf("%d ",A[i]);
	}
	printf("\n");
}
int main()
{
	read();
	quick_sort(A,0,n-1);
	write();
}

 快排的優化

若是本身在草稿紙上寫寫整個快排的步驟,不難發現對於逆序的序列,上面的快排版本的複雜度是O(n2),因此有優化。很簡單,每次隨機的選取一個元素做爲主元。對象

-end-blog

相關文章
相關標籤/搜索