快速排序是從氣泡排序演變而來,快速排序之所以快,是因為使用了分治法。
同氣泡排序一樣,快速排序也屬於交換排序,通過元素之間的比較和交換位置來達到排序的目的。
快速排序是在每一輪挑選乙個基準元素,並讓其他比它大的元素移動到數列的一邊,比它曉得元素移動到數列的另一邊,從而把數列拆解成兩個部分。
在分治法的思想下,原數列在每一輪都被拆分成兩部分,每一部分在下一輪又分別被拆分成兩部分,直到不可再分為止。
假如元素個數是n,那麼平均情況下需要logn輪,因此快速排序的平均演算法複雜度是o(nlogn),最壞情況是o(n^2)。
元素的交換:
1.選基準元素;2.陣列分為大於和小於基準的兩份。
實現方法:(1).雙邊迴圈法;(2).單邊迴圈法。
首先選定基準元素pivot,並且設定兩個指標left和right,指向數列的最左和最右兩個元素。
第1次迴圈:從right指標開始,讓指標指向元素和基準元素做比較。如果大於或等於pivot,則指標向左移動;如果小於pivot,則right指標停止移動,切換到left指標。
輪到left指標行動,讓指標所指向的元素和基準元素做比較,如果小於或等於pivot,則指標向右移動;如果大於pivot,則left指標停止移動。
1.雙邊迴圈法:
using system;
namespace csharptest01
// 得到基準元素位置
int pivotindex =
}/// /// 分治(雙邊迴圈法)
///
private static int partition(int arr, int startindex, int endindex)
// 控制left指標比較並右移
while (left < right && arr[left] <= pivot)
// 交換left和right指標所指向的元素
if (left < right)}}
static void main(string args)}}
上述**中,quicksort通過遞迴的方式,實現了分而治之的思想。
partition實現元素交換,讓元素依據自身大小,分別交換到基準的左右。這裡的交換方式是雙邊迴圈法。
2.單邊迴圈法:
開始和雙邊迴圈法相似,首先選定基準元素pivot。同時,設定乙個mark指標指向數列起始位置,這個mark指標代表小於基準元素的區域邊界。
接下來,從基準元素的下乙個位置開始遍歷陣列。如果遍歷到的元素大於基準元素,就繼續往後遍歷 。
如果遍歷到的元素小於基準元素,則需要做兩件事:第一,把mark指標右移1位,因為小於pivot的區域邊界增大了1;第二,讓最新遍歷到的元素和mark指標所在的元素交換位置,因為最新遍歷的元素屬於小於pivot的區域。
隨後,讓3和mark指標所在位置的元素交換。
按照這個思路,繼續遍歷。
using system;
using system.collections;
namespace csharptest01
// 得到基準元素
int pivotindex = partition(arr, startindex, endindex);
// 根據基準元素,分成兩部分進行遞迴排序
quicksort(arr, startindex, pivotindex - 1);
quicksort(arr, pivotindex + 1, endindex);
}/// /// 分治(單邊迴圈法)
///
private static int partition(int arr, int startindex, int endindex)
}arr[startindex] = arr[mark];
arr[mark] = pivot;
return mark;
}static void main(string args)
;quicksort(arr, 0, arr.length - 1);
foreach (var item in arr)}}
}
3.非遞迴實現:把原本的遞迴實現轉化成乙個棧的實現,在棧中儲存每一次方法呼叫的引數。
/// /// 分治(單邊迴圈法)
///
private static int partition(int arr, int startindex, int endindex)
}arr[startindex] = arr[mark];
arr[mark] = pivot;
return mark;
}static void main(string args)
;quicksort(arr, 0, arr.length - 1);
foreach (var item in arr)}}
}每一次迴圈,都會讓棧頂元素出棧,通過partition方法進行分治,並且按照基準元素的位置分成左右兩部分,左右兩部分再分別入棧。當棧為空時,說明排序已經結束,退出迴圈。
C 演算法之快速排序(十)
引用部落格的介紹 快速排序 演算法思想 基於分治的思想,是氣泡排序的改進型。首先在陣列中選擇乙個基準點 該基準點的選取可能影響快速排序的效率,後面講解選取的方法 然後分別從陣列的兩端掃瞄陣列,設兩個指示標誌 low指向起始位置,high指向末尾 首先從後半部分開始,如果發現有元素比該基準點的值小,就...
演算法 排序演算法之快速排序
很受打擊啊啊啊啊啊!這道排序題我很久之前就做過,而且當時沒用20分鐘就搞定了,可是,今天在公司做完手上的活之後打算刷題時,又心血來潮的想重做一遍,心想反正也花不了多少時間,結果。血崩了。要求 對於乙個int陣列,請編寫乙個快速排序演算法,對陣列元素排序。給定乙個int陣列a及陣列的大小n,請返回排序...
演算法 排序演算法之快速排序
快速排序是由東尼 霍爾所發展的一種排序演算法。在平均狀況下,排序 n 個專案要 nlogn 次比較。在最壞狀況下則需要 n2 次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他 nlogn 演算法更快,因為它的內部迴圈 inner loop 可以在大部分的架構上很有效率地被實現出來。快速排序...