日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【算法】快速排序

發布時間:2025/6/17 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【算法】快速排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

算法 系列博客

【算法】刷題范圍建議 和 代碼規范
【算法】復雜度理論 ( 時間復雜度 )

【字符串】最長回文子串 ( 蠻力算法 )
【字符串】最長回文子串 ( 中心線枚舉算法 )
【字符串】最長回文子串 ( 動態規劃算法 ) ★
【字符串】字符串查找 ( 蠻力算法 )
【字符串】字符串查找 ( Rabin-Karp 算法 )

【算法】雙指針算法 ( 雙指針算法分類 | 相向雙指針 | 有效回文串 )
【算法】雙指針算法 ( 有效回文串 II )
【算法】哈希表 ( 兩數之和 )

【算法】快速排序


文章目錄

  • 算法 系列博客
  • 一、快速排序思想
  • 二、快速排序代碼





一、快速排序思想



快速排序的思想 :整體有序 , 后 局部有序 , 分治算法 ;

先從數組中 挑選出一個數 a , 然后 進行分割 , 將數組分割成兩部分 , 左半部分 小于等于 a , 右半部分 大于等于 a ;
此時數組左半部分肯定小于右半部分 ;
然后分別對 左半部分 和 右半部分 再次挑選一個數 , 進行分割 ;
遞歸進行分割操作 , 直到數組中所有元素排序完成 ;


分割數組時 , 分割條件是小于等于 / 大于等于的原因 :
分割時 , 挑選的數 a , 如果數組元素為 a , 則該元素即可以在左邊 , 又可以在右邊 ;
如果數組中除幾個數之外 , 其它全都是一樣的數 , 如 [1,1,1,1,1,1,1,2] , 挑選數字時 , 大概率選中 1 , 此時如果要求左半部分嚴格小于 1 , 此時 左半部分沒有任何數值 , 很容易出現不均勻的劃分 ;


快速排序的 理想劃分 是每次劃分 , 劃分的左邊和右邊的元素個數基本差不多 , 遞歸時不會出現極端情況 ,





二、快速排序代碼



整數排序 : https://www.lintcode.com/problem/463/


下面代碼中有三個要點

  • 分割中心點選取 ;
  • 指針限制條件 ;
  • 分割時判定要左右交換元素的條件 ;

取中心點, 一般取 start 與 end 索引的 中心索引對應的數組元素值 ;
如下取中間值是強行指定的, 也可以隨機指定 , 指定 start 與 end 之間的一個隨機值 ;
盡量不選取 start 和 end 索引的值 , 如果選取開始/結束值 , 作為分割點 , 假如該數組是按照升序或降序排列 , 可能出現極端情況 ;

指針限制條件 , 分割遍歷時的兩個指針的條件是 left <= right , 這里不能是 left < right ;
如果使用 left < right 會造成死循環遞歸 , 導致棧溢出 ;
使用 [3,2,1,4,5] 進行推導 , 即可出現死循環 ;

判定左右元素交換時 , 必須用 array[left] < pivot 和 array[right] > pivot , 不能使用 array[left] <= pivot 和 array[right] >= pivot , 否則會造成死循環遞歸 , 導致棧溢出 ;
使用 [3,2,1,4,5] 進行推導 , 即可出現死循環 ;


快速排序的時間復雜度是 O(nlog?n)O(n \log n)O(nlogn) ;


代碼示例 :

class Solution {/*** 快速排序* @param A*/public void sortIntegers(int[] A) {if (A == null || A.length == 0) {return;}quickSort(A, 0, A.length - 1);}// 將 array 數組中 start 到 end 之間的元素進行排序private void quickSort(int[] array, int start, int end) {if (start >= end) {// start 如果等于 end, 說明就一個元素, 不用排序// start 正常情況下不會大于 endreturn;}// 設置兩個指針, 分別指向頭尾int left = start, right = end;// 1. 分割操作第一步 : 取中心點// 取中心點, 一般取 start 與 end 索引的中心索引對應的數組元素值// 如下取中間值是強行指定的, 也可以隨機指定 , 指定 start 與 end 之間的一個隨機值// 盡量不選取 start 和 end 索引的值int pivot = array[(start + end) / 2];// 2. 分割操作第二部 : 進行數組元素分割// 注意此處, left 小于等于 right , 不能是小于while (left <= right) {// 找到一個不屬于左邊部分的元素, 將其交換到右邊while (left <= right && array[left] < pivot) {// 如果遇到一個元素不屬于左邊, 則退出循環left++;}// 找到一個不屬于右邊部分的元素, 將其交換到左邊while (left <= right && array[right] > pivot) {// 如果遇到一個元素不屬于右邊, 則退出循環right--;}// 交換上述檢測出來的需要交換的元素if (left <= right) {int tmp = array[left];array[left] = array[right];array[right] = tmp;// 交換完畢后, 繼續向后遍歷left++;right--;}// 交換完畢后, 繼續循環, 該循環退出的條件是 left >= right}// 分割完畢后, 繼續遞歸// 如果按照中心點分割完畢的話, 上面的循環退出, left >= right// 索引的分布如下 : start , right, left, endquickSort(array, start, right);quickSort(array, left, end);} }

總結

以上是生活随笔為你收集整理的【算法】快速排序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。