排序是演算法中比較基礎常見的問題,排序演算法有很多種,如插入排序、歸併排序、堆排序、快速排序、計數排序、基數排序和桶排序。今天來講講快速排序。
對於包含n個數的輸入陣列來說,快速排序的最壞情況時間複雜度為o(n²),雖然最壞情況時間複雜度很差,但是快速排序通常是實際排序應用中最好的選擇,因為它的平均效能非常好:它的期望時間複雜度是o(nlgn)。
快速排序使用到了分治的思想,所以我們也按照分之策略的三個步驟來描述快排的過程:
分解:陣列a[p…r]被劃分為兩個(可能為空)子陣列a[p…q-1]和a[q+1…r],使得a[p…q-1]中的每個元素都小於等於a[q],而a[q]也小於等於a[q+1…r]裡的每個元素。
解決:通過遞迴呼叫快速排序,對子陣列a[p…q-1]和a[q+1…r]進行排序。
合併:經過所有的遞迴排序後,陣列已經是有序的,所以不需要合併操作。
下面是偽**,分為兩個過程:
quicksort(a,p,r)
if p < r
q = partition(a,p,r)
quicksort(a,p,q-1)
quicksort(a,q+1,r)
partition(a,p,r)
x = a[r]
i = p-1
for j =p to r-1
ifa[j] <= x
i = i + 1
exchange a[i] with a[j]
exchange a[i+1] with a[r]
return i + 1
partition過程是快排的核心,在這個過程中總是選擇乙個x=a[r]作為主元,並圍繞它來劃分陣列,經過乙個partition後,該主元在陣列中的位置已經排好了,不需要對該元素再進行位置交換了,只需要再對該主元前和後的兩個子陣列進行遞迴排序就行了。
實現**如下:
public
class
quicksort ;
quicksort(a, 0, a.length - 1);
for (int i : a)
}public
static
void
quicksort(int a, int p, int r)
}private
static
intpartition(int a, int p, int r)
}exchange(a, i + 1, r);
return i + 1;
}/**
* 交換陣列內的兩個元素
*@param a 陣列
*@param i j 需要交換元素的兩個下標值
*/public
static
void
exchange(int a, int i, int j)
}
結果截圖:
演算法學習之路,排序之快速排序(Java實現)
快速排序思路 首先是定義乙個變數key,把陣列的第乙個元素的值賦給key,然後定義兩個變數start,end指向陣列的第乙個元素和最後乙個元素。然後從後往前遍歷,一直end 知道下標為end的值小於key,就交換下標為start,end的值,然後再從前遍歷,一直start 直到下標為start的值大...
演算法學習(二)快速排序(下)
快速排序採取的是分治法,所以怎麼把乙個無序的陣列以某個點為中界來將其拆分成有序的兩部分,這是其快 排的核心方法。在上一章中,是一開始提出來的 快速排序 但是這個世界上在某些地方總會有些牛人,一點一點地去優化,提出更有意思,更簡單的方法。看下圖,這是快排另乙個經典的拆分方法 1 這裡是將陣列的最後乙個...
演算法學習 快速排序
快速排序 分治演算法 const int n 1e6 10 int a n a 待排序陣列,l 排序陣列的起始下標,r 排序陣列的結束下標 void quick sort int a,int l,int r 遞迴的終止條件 int x a l 選取排序的比較物件 int i l 1 設定排序的左指標...