常用排序演算法 以最簡單的方式理解快速排序

2021-08-09 13:25:58 字數 2029 閱讀 1532

本小白覺得快速排序是最難理解的排序演算法,特別是程式**的實現,花了兩個小時終於給看懂了…

首先是設定了乙個基準pivot,預設是第乙個或者最後乙個,(假設是第乙個數)然後和後面的數進行比較,要是大於基準,就在原地不變,要是小於基準,就放在基準後面,按照比較順序將後面小於基準的數字逐一排列,等遍歷了一輪之後會發現,局勢演變成了:基準【小於基準】【小於基準的最後乙個元素】【大於基準】這樣的結構,還沒完,然後把基準和小於基準的最後乙個元素交換位置,這樣就完成了一輪。

可以看到,每一輪都是完成基準的歸位,等所有的數被當成基準歸位之後,這個數串就是正序的了。

這裡是以最後乙個元素作為基準,形成【小於基準】【大於基準】基準,這樣的結構。

**實現:

#include 

// 分類 ------------ 內部比較排序

// 資料結構 --------- 陣列

// 最差時間複雜度 ---- 每次選取的基準都是最大(或最小)的元素,導致每次只劃分出了乙個分割槽,需要進行n-1次劃分才能結束遞迴,時間複雜度為o(n^2)

// 最優時間複雜度 ---- 每次選取的基準都是中位數,這樣每次都均勻的劃分出兩個分割槽,只需要logn次劃分就能結束遞迴,時間複雜度為o(nlogn)

// 平均時間複雜度 ---- o(nlogn)

// 所需輔助空間 ------ 主要是遞迴造成的棧空間的使用(用來儲存left和right等區域性變數),取決於遞迴樹的深度,一般為o(logn),最差為o(n)

// 穩定性 ---------- 不穩定

void swap(int a, int i, int j)

int partition(int a, int left, int right) // 劃分函式

}swap(a, tail + 1, right); // 最後把基準放到前乙個子陣列的後邊,剩下的子陣列既是大於基準的子陣列

// 該操作很有可能把後面元素的穩定性打亂,所以快速排序是不穩定的排序演算法

return tail + 1; // 返回基準的索引

}void quicksort(int a, int left, int right)

//每一輪都是完成對基準的歸位,基準把數字分成兩部分,分別用遞迴實現

int main()

; // 從小到大快速排序

int n = sizeof(a) / sizeof(int);

quicksort(a, 0, n - 1);

printf("快速排序結果:");

for (int i = 0; i < n; i++)

printf("\n");

return

0;}

上面那個**比較難理解,但是符合我所分析的。

然後貼乙個容易理解的,另一種思考方式:

設定兩個哨兵,乙個基準,假設把第乙個元素當做基準,然後乙個哨兵j從右邊開始尋找比基準大的,另乙個哨兵i從左邊開始尋找比基準小的,直到兩個哨兵相遇。這裡要注意一點,從右向左找比基準大的哨兵j一定要先行動,有兩點:1.因為到最後相遇的時候所在的元素比基準大,那麼它待在原地不動,遇到哨兵i的時候就退出迴圈,假如是i先行動,交換了之後就已經完成布局,i就位於比基準大的模組;2.假如是比基準小的,那麼後面就會直接和基準實現交換。

#include 

int a[101],n;//定義全域性變數,這兩個變數需要在子函式中使用

void quicksort(int left,int right)

} //最終將基準數歸位

a[left]=a[i];

a[i]=temp;

quicksort(left,i-1);//繼續處理左邊的,這裡是乙個遞迴的過程

quicksort(i+1,right);//繼續處理右邊的 ,這裡是乙個遞迴的過程

} int main()

最容易理解的排序演算法

排序不難,但是有時候我們容易出錯,容易混淆等等,我們慢慢來分析,從最簡單的開始慢慢深入理解。插入排序 直接插入排序 每一步將乙個待排的記錄根據關鍵字的大小插入已經排好序的那部分裡邊去,直到所有的都插完為止。我們來看例子來分析 初始大小 57 68 59 52 1 第乙個數是57,就乙個數,所以就預設...

最簡單的排序演算法 氣泡排序

原理 比較兩個相鄰的元素,將值大或值小的元素交換至右端。思路 依次比較相鄰的兩個數,將小數放在前面,大數放在後面。即在第一趟 首先比較第1個和第2個數,將小數放前,大數放後。然後比較第2個數和第3個數,將小數放前,大數放後,如此繼續,直至比較最後兩個數,將小數放前,大數放後。重複第一趟步驟,直至全部...

桶排序(最簡單的排序演算法)

桶排序的基本思想 將乙個資料表分割成許多buckets,然後每個bucket各自排序,或者用不同的排序演算法,遞迴的 使用bucket sort 演算法,也是一種典型的divide and conquer分而治之的策略,它是一種分布式的排序,介於msd基數排序和lsd基數排序之間 def bucke...