摘要:分治快速排序以下簡稱快排的核心思想是分治法。第二個元素大于,放于右側第三個元素小于,放于左側以此類推,最后一個元素放置完畢后是這樣的重復。此時從左到右讀出圖中曾作為基準值的元素菱形,我們發現已經排序好了。
分治
快速排序(以下簡稱“快排”)的核心思想是分治法。可以說,分治提供了另一種解決問題的思路。舉個例子來進行說明,抓穩扶好,直接開車了……
舉例現有一個集合{4,8,2,5,7,-1,3},我們將對它進行從小到大排序:
1.選取第一個元素4作為基準值,后面的元素逐個和這個基準值比較大小
顯然,要么大于,要么小于( 暫不考慮相等的情況)。
2.按比較大小結果進行安置:大于基準值的元素,置于它的左側;小于基準值的元素,置于它的右側(如果有相等情況,左右隨意)
為好理解,畫出了數軸,將"基準值4"作為中軸線。第二個元素8大于4,放于右側;第三個元素2小于4,放于左側……以此類推,最后一個元素放置完畢后是這樣的
3.“重復”。先拋開右側的big集合,專注于左側集合{2,-1,3}。此時,我們把它當作source,重復第一步的操作。
如此重復下去,直到只剩下一個元素的情況。
此時從左到右讀出圖中曾作為基準值的元素(菱形)——-1,2,3,4,我們發現已經排序好了。最后給出完整的操作示意圖:
每次根據條件劃分成兩部分,劃分后每部分分別治理,即分治。
遞歸上面的例子中,第三步叫“重復”其實并不準確,真正的名字是遞歸。
每個遞歸函數都有兩部分:
基線條件:函數不再調用自己,即退出無限循環調用的條件
遞歸條件:調用自己,且通過一次次調用會逐步靠攏基線條件
拿上一篇文章(【算】選擇排序和二分查找)里聊過的二分查找舉例:
/** * 二分查找,遞歸版 * @param target * @param source * @return */ public static int doFind(int target,List快排source){ if(CollectionUtils.isEmpty(source)){ throw new RuntimeException("集合為空"); } int halfIndex = source.size()/2; int halfElement = source.get(halfIndex).getVal(); if(target==halfElement){ //基線條件:如果目標target和中間數相等,bingo!找到了,返回索引 return source.get(halfIndex).getIndex(); }else if(source.size()==1){ //另一個基線條件:就剩下最后一個元素了,仍然與目標target不符,則返回“目標不存在” throw new RuntimeException("目標不存在"); }else{ //遞歸條件:選取符合條件的那一半集合,遞歸調用自己 if (target < halfElement) { List tempSource = source.subList(0, halfIndex); return doFind(target, tempSource); } else { List tempSource = source.subList(halfIndex, source.size()); return doFind(target, tempSource); } } }
掌握了遞歸和分治思想后,快速排序就只剩下編碼部分了:
/** * 快排 * @param source * @return */ public static ListdoOrder(List source){ if(source.size()<=1){ //基線條件 return source; } int temp = source.get(0); List lowElements = new LinkedList<>(); List highElements = new LinkedList<>(); for(int i=1,len=source.size();i res = new LinkedList<>(lowElements); res.add(temp); res.addAll(highElements); return res; }
快排的平均時間復雜度為O(n log n)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68860.html
摘要:代碼片段語言組織能力有限,直接上代碼排序算法之快速排序參數為需要排序的數組參數為數組的起始下角標即參數為數組的最后下角標即經過一輪排序,已經將數組分為左右兩部分進行遞歸排序總結快速排序的精髓在于分治思想,分而治之,它的時間復雜度為。 算法簡述 所謂快速排序算法是基于交換排序和遞歸思想的,它的速度的確如名字所示——快!并且這種一算一般被用作數量級比較大的數據當中,在大數據中有著很重要的地...
摘要:概念這里借用百度百科的一張圖來,非常形象快速排序算法是對冒泡算法的一個優化。獲取已經打亂了順序的數組快速排序這里引用的是我之前寫的冒泡算法排序冒泡運行結果 概念 這里借用百度百科的一張圖來,非常形象:showImg(https://segmentfault.com/img/bVdlR6); 快速排序算法是對冒泡算法的一個優化。他的思想是先對數組進行分割, 把大的元素數值放到一個臨時數...
摘要:數組在中使用度非常頻繁,我總結了一些在數組中很常見的問題。否則返回語言類型返回數組中滿足提供的測試函數的第一個元素的索引。接受兩個參數和,代表需要截取的數組的開始序號和結束序號。其中表示添加的元素個數。 數組在javascript中使用度非常頻繁,我總結了一些在數組中很常見的問題。 關于數組中的方法非常多,我總結了一張表來大致了解數組中的方法 Array中的方法 含義 改變原數組 ...
摘要:本篇博客我要來和大家一起聊一聊數據結構初階中的最后一篇博客八大經典排序算法的總結,其中會介紹他們的原來,還有復雜度的分析以及各種優化。快速排序遞歸版本快速排序是于年提出的一種二叉樹結構的交換排序方法。 ...
閱讀 3266·2021-09-02 15:41
閱讀 2829·2021-09-02 09:48
閱讀 1368·2019-08-29 13:27
閱讀 1157·2019-08-26 13:37
閱讀 832·2019-08-26 11:56
閱讀 2479·2019-08-26 10:24
閱讀 1638·2019-08-23 18:07
閱讀 2615·2019-08-23 15:16