思想:
從陣列中選取乙個數作為基準值,按照從大到小排序小於基準值的放在基準值的左邊,大於基準值的在基準值的右邊
核心partition過程:
選取陣列第乙個元素作為基準值,小於區[left+1,j-1],大於等於區[j,i-1],讓變數i從left+1位置開始遍歷陣列,j變數位置是小於區間的而最後乙個數,若是i位置的元素是小於基準值的數,就讓小於區間增大,即小於基準值的數與大於等於區的第乙個數進行交換,小於區擴大,依次比較交換,直到遍歷整個陣列。最終返回基準值的位置,基準值左邊為小於區間,右邊為大於區間,遞迴即可完全排序
private
static
intpartition1
(int
arr,
int left,
int right)
else
}//直到i遍歷完序列中所有數後,將小於區最後乙個數與基準值進行交換
swap
(arr,left,j)
;return j;
}
private
static
void
swap
(int
arr,
int i,
int j)
}
存在問題:當陣列中等於基準值的元素太多時,會將等於基準值的元素劃分在大於區,這是兩個區域的大小會嚴重失衡,會導致分割槽的次數大大增加,這時排序的時間複雜度就會退化,從o(nlogn)退化為o(n^2)
優化:此時,我們優化為雙路快排,雙路快排的思想是,定義兩個變數,乙個從陣列的左邊開始進行遍歷,乙個從序列的右邊開始進行遍歷,把右邊遍歷時比基準值小的數與左邊遍歷比基準值大的數進行交換,依次比較交換,直到兩個變數相等,這樣的方法使得等於基準時的數盡可能平均的分攤在兩個區域,解決失衡問題
核心partition過程:
private
static
intpartition
(int
arr,
int left,
int right)
while
(j >= left+
1&& arr[j]
> val)
if(i > j)
swap
(arr,i++
,j--);
}swap
(arr,left,j)
;return j;
}
存在問題:如果這是乙個有序或接近有序的序列,如果我們選擇最後乙個或第乙個元素作為基準元素,那每次得到的兩個分割槽是不均等的,我們需要進行大約n次分割槽操作才能完成整個快排操作,這是快排的時間複雜度就會退化到o(n^2)
**解決:**引入隨機快排,在選取基準值時,隨機選取乙個元素,將這個隨機的元素與陣列首元素進行交換,這是每次選取到最大最小值的概率就會無限小,此時解決有序導致的時間複雜度退化問題
思想:將陣列按照基準值分為三部分:大於區、小於區、等於區,分割槽的過程中等於基準值的元素已經到了最終位置,在下一次的遞迴排序時只需要進行大於和小於區的處理,直到將序列排序成功,對於等於值較多的序列,這種方法效率很高
核心partation過程:
讓變數從陣列開始進行遍歷,當遇見比基準值小的元素,將小於基準值的元素與等於區第乙個元素進行交換,(演算法不穩定)小於區擴大,當遇見比基準值大的元素,將大於基準值的元素與等於區最後乙個元素進行交換,大於區擴大,一次排序後返回等於區的陣列範圍
private
static
int[
]partition
(int
arr,
int left,
int right)
else
if(arr[l]
> val)
else
}//返等於區
return
newint
;}
分析:
穩定性:不穩定
時間複雜度:最好:o(nlogn) 最壞:o(n^2)
恐慌間複雜度:遞迴過程最好 o(logn) 最壞o(n)
排序演算法總結(快速排序)
終於不用改 了,希望文章大修順利!穩定的演算法 不穩定的演算法 內部排序 排序過程不涉及內 外存交換 外部排序 排序過程有內 外存交換 in place sort 不占用額外記憶體或占用常數的記憶體 插入排序 選擇排序 氣泡排序 堆排序 快速排序。out place sort 歸併排序 計數排序 基...
排序演算法總結 快速排序
快速排序的一般步驟如下 1 先從數列中取出乙個數作為基準數。2 分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。3 再對左右區間重複第二步,直到各區間只有乙個數。來自於 啊哈!演算法 這裡需要解釋一下為什麼每次交換的時候都需要右邊的哨兵先走 最主要是相遇點的問題,演算法的...
排序演算法總結 快速排序
前面說的氣泡排序是一種交換排序。交換排序還有一種演算法,就是快速排序演算法。快速排序的核心思想是分而治之。意思就是選出乙個基準 可以是第乙個元素,也可以是最後乙個。為了方便我們選取第乙個 將小於這個基準的全部元素都放在這個基準的左邊,大於這個基準的全部元素都放在基準的右邊。然後分別對左右兩個陣列在進...