快速排序的思想與歸併排序思想類似,都是採用分治法的思想。將乙個陣列a[l...r]
使用快速排序可以分解為三個主要的步驟:
通過隨機演算法獲得陣列a
中的乙個下標k,將
a[k]
與a[r]
交換。將陣列分解成左右兩個陣列,左邊陣列的值均小於a[r]
,右邊陣列的值均不小於
a[r]
。分別對左右兩個陣列進行排序,這兩個陣列的大小均比a
小。通過上面的步驟,我們就可以得到快速排序的乙個框架:
1void quicksortcore(int data, int start, int
end)
29 }
從上面的**中可以看出,分解a
陣列為左右兩個陣列是快速排序演算法的關鍵,這個問題本質上為:對陣列
a中的某個值
a[k](k
為陣列的下標),將小於
a[k]
的數存放在陣列
a的前面,將不小於
a[k]
的數存放在陣列
a的後面,分界線為x。
解決該問題的一種很直觀的方法就是先將a[k]
與a[r]
交換,然後用兩個下標i、
j,i表示
a[0~i]
中的數都小於
a[r],j
從0~r-1
遍歷陣列
a。如果發現
a[j]
小於a[r]
,則將a[i + 1]
與a[j]
交換,並同時增加i和
j,之所以可以這樣是因為
a[i + 1]
要麼不小於
a[r]
,要麼與
a[j]
相同;如果
a[j]
不小於m
,則只遞增
j。最後將
a[i + 1]
與a[r]
交換,i+1
為左右陣列的分界線x。
1int partition(int data, int start, int
end)
214 i++;
15 swap(data + i, data +end);
16return
i;17 }
解決問題的另乙個方法是先將a[k]
與a[l]
交換,並用乙個臨時變數p儲存
a[k]
,也使用兩個下標i和
j,分別初始化為l和
r。開始用
j從陣列右邊遍歷,知道發現
a[j] < p
為止,將
a[j]
賦值給a[i]
,並讓i加1
,然後用
i從陣列的左邊遍歷,知道發現
a[i] > p
為止,將
a[i]
賦值給a[j]
,並讓j減1
,然後重新開始前面的遍歷,知道
i == j
為止。最後將
p賦值給
a[i]
,此時i
為左右陣列的分界線x。
1int partition(int data, int start, int
end)
223 data[i] =temp;
24return
i;25 }
前面兩個方法中,第二個方法比第乙個方法要好些,第二個方法用賦值替代了第乙個方法中的交換。
**中的getrandom函式是用來隨機獲得start到end之間的乙個值,它可以用rand庫函式實現。
經典排序演算法之二 選擇排序
思想 假設給定乙個大小為n的陣列,從中選出最大的值 記錄下標 與下標n i的值進行交換 i 1,n 1 i為迴圈次數 即遍歷一次交換一次,每次遍歷確定乙個最大值。優化思路 使用一種快速查詢最值的方法可降低選擇排序的時間複雜度,例如使用堆這種資料結構,可在o logn 的情況下找到最值 普通 cmp ...
經典排序之二 快速排序 二路歸併
快速排序,顧名思義效率相比較其他排序方法高,它是一種交換排序 基本思路是 3 對左右兩個陣列做1,2操作,直至陣列裡只有乙個數值 function quicksort arr splice 方法向 從陣列中新增 刪除專案,然後返回被刪除的專案。會改變原陣列 方法對乙個數進行往下取整 小於等於x,且與...
java 演算法基礎之二快速排序演算法
所謂的快速排序的思想就是,首先把陣列的第乙個數拿出來做為乙個key,在前後分別設定乙個i,j做為標識,然後拿這個key對這個陣列從後面往前遍歷,及j 直到找到第乙個小於這個key的那個數,然後交換這兩個值,交換完成後,我們拿著這個key要從i往後遍歷了,及i 一直迴圈到i j結束,當這裡結束後,我們...