文章編號:10740時間:2024-09-29人氣:
快速排序是一種高效的排序算法,其核心思想是通過一趟排序?qū)?shù)組分割成兩部分,一部分所有數(shù)據(jù)小于另一部分,然后遞歸地對這兩部分進行排序。 理解這個過程的關鍵在于遞歸調(diào)用自身。
首先,我們從一個待排序的數(shù)組 A[1]...A[N] 出發(fā)。 選擇一個基準元素,通常選擇第一個元素作為起點,將其稱為 X。 接著,設立兩個指針 I 和 J,分別指向數(shù)組的起始和結(jié)束。
一趟快速排序 如此進行:從 J 開始向前搜索,遇到小于 X 的元素就將其與 I 位置的元素交換;同時,從 I 向后搜索,找到大于 X 的元素進行交換。 這個過程會一直持續(xù),直到 I 和 J 指針相遇。
值得注意的是,快速排序的 遞歸特性:當劃分完成后,對左右兩部分再次執(zhí)行相同的排序步驟,直到每個子數(shù)組只剩下一個元素或為空,遞歸結(jié)束。 這是一種典型的分治策略,每一次遞歸都將問題規(guī)模縮小,直至達到基本情況。
然而,快速排序并非 穩(wěn)定排序,相同元素的相對位置可能會在排序過程中改變。 這源于交換操作,可能會打亂相同值的順序。
在代碼實現(xiàn)中,遞歸調(diào)用的偽代碼如下:
總的來說,快速排序的遞歸過程如同一場精密的舞者編排,每個元素都在有序與無序之間優(yōu)雅地切換,直至整個序列井然有序。 希望這篇文章能幫助你深入了解快速排序的遞歸之美。
常見排序算法(冒泡,選擇,快速)的C語言實現(xiàn)要實現(xiàn)這幾種算法的關鍵是要熟悉算法的思想。
簡單的說,冒泡排序,就如名字說的,每經(jīng)過一輪排序,將最大的數(shù)沉到最底部。
選擇排序的思想是將整個數(shù)列,分為有序區(qū)和無序區(qū)。
每輪排序,將無序區(qū)里的最小數(shù)移入到有序區(qū)。
快速排序的思想是以一個數(shù)為中心,通常這個數(shù)是該數(shù)列第一個數(shù),將整個數(shù)列分為兩個部分,一個部分是大于這個數(shù)的區(qū)域,一個部分是小于這個數(shù)的區(qū)域。
然后再對這兩個部分的數(shù)列分別排序。
如果將數(shù)列分為兩個部分是通過,一方面從后向前的搜索,另一方面從前向后的搜索來實現(xiàn)的。
具體的參考后面的來自網(wǎng)絡百科的文檔。
從這幾個簡單的排序算法上看,有幾個特點:冒泡排序是最簡單的,也是最穩(wěn)定的算法。
選擇排序不太穩(wěn)定,但是效率上較冒泡還是有較大的提升。
其實在分析的過程中就能發(fā)現(xiàn),選擇排序和冒泡排序相比,中間少了很多的交換過程,和比較的次數(shù),這個應該是時間較少的原因。
選擇排序能夠滿足一般的使用。
當比較的數(shù)超過以萬為單位時,選擇排序也還是要一點時間的。
快速排序據(jù)說是最快的。
這個可以從思想上看的出來。
,當記錄較多的時候,快速排序的比較循環(huán)次數(shù)比上面2個都要少。
但是在具體的實現(xiàn)過程中,并不見得如此。
這是因為遞歸效率的低下導致的。
當然,估計在實際使用過的過程,快速排序估計都會使用非遞歸操作棧的方式來實現(xiàn)。
那樣應該會效率高傷不少。
估計我會在后期出一個快速排序的非遞歸實現(xiàn)來真正比較它們3個性能。
在下面的程序中,可以通過調(diào)高N的數(shù)字就能看的出來冒泡排序和選擇排序性能的差異。
在N較小,大概幾百的時候,是看不出來的。
N較大的的時候,比如N=1000或者N=的時候,快速排序的遞歸實現(xiàn)就會卡死在那里了,出不了結(jié)果。
以下是具體的代碼:/*** 常見排序算法比較 */#include
快速排序思想:通過對數(shù)據(jù)元素集合Rn 進行一趟排序劃分出獨立的兩個部分。 其中一個部分的關鍵字比另一部分的關鍵字小。 然后再分別對兩個部分的關鍵字進行一趟排序,直到獨立的元素只有一個,此時整個元素集合有序。 快速排序的過程,對一個元素集合R[ low ... high ] ,首先取一個數(shù)(一般是R[low] )做參照 , 以R[low]為基準重新排列所有的元素。 所有比R[low]小的放前面,所有比R[low] 大的放后面,然后以R[low]為分界,對R[low ... high] 劃分為兩個子集和,再做劃分。 直到low >=high 。 比如:對R={37, 40, 38, 42, 461, 5, 7, 9, 12}進行一趟快速排序的過程如下(注:下面描述的內(nèi)容中元素下表從 0 開始):開始選取基準 base = 37,初始位置下表 low = 0 , high = 8, 從high=8,開始如果R[8] < base ,將high位置中的內(nèi)容寫入到R[low]中, 將high位置空出來, low = low +1 ;從low開始探測,由于low=1 , R[low] > base ,所以將R[low]寫入到R[high] , high = high -1 ;檢測到low < high ,所以第一趟快速排序仍需繼續(xù):此時low=1,high=7,因為 R[high] < base ,所以將 R[high] 寫入到到R[low]中,low = low + 1;從low開始探測,low = 2 , R[low] >base ,所以講R[low]寫入到R[high],high=high-1;繼續(xù)檢測到 low 小于high此時low=2,high=6,同理R[high] < base ,將R[high] 寫入到R[low]中,low=low+1;從low繼續(xù)探測,low = 3 , high=6 , R[low] > base , 將R[low]寫入到R[high]中,high = high-1;繼續(xù)探測到low小于high此時low=3,high=5,同理R[high] < base,將R[high]寫入到R[low]中,low = low +1;從low繼續(xù)探測,low = 4,high=5,由于R[low] > base , 將R[low]寫入到R[high]中,high = high -1 ;此時探測到low == high == 4 ;該位置即是base所在的位置,將base寫入到該位置中.然后再對子序列Rs1 = {12,9,7,5} 和 Rs2={461,42,38,40}做一趟快速排序,直到Rsi中只有一個元素,或沒有元素。 快速排序的Java實現(xiàn):private static boolean isEmpty(int[] n) {return n == null || == 0;}// ////////////////////////////////////////////////////** * 快速排序算法思想——挖坑填數(shù)方法: * * @param n 待排序的數(shù)組 */public static void quickSort(int[] n) {if (isEmpty(n))return;quickSort(n, 0, - 1);}public static void quickSort(int[] n, int l, int h) {if (isEmpty(n))return;if (l < h) {int pivot = partion(n, l, h);quickSort(n, l, pivot - 1);quickSort(n, pivot + 1, h);}}private static int partion(int[] n, int start, int end) {int tmp = n[start];while (start < end) {while (n[end] >= tmp && start < end)end--;if (start < end) {n[start++] = n[end];}while (n[start] < tmp && start < end)start++;if (start < end) {n[end--] = n[start];}}n[start] = tmp;return start;}在代碼中有這樣一個函數(shù):public static void quickSortSwap(int[] n, int l, int h)該函數(shù)可以實現(xiàn),元素集合中特定的l到h 位置間的數(shù)據(jù)元素進行排序。
首先這個程序不是快速排序。 它是一個遞歸全排列生成的程序。 它是根據(jù)輸入的順序生成的。 只要你輸入 CBA ,輸出就是倒序的了。 你這里沒說清輸入的格式,所以沒法作出改動。 var str:string;l:longint;f:array[1..8]of boolean;//用來記錄每個字母是否用過procedure dfs(dep:longint;ans:string);vari:longint;beginif dep>l then//若l個字母都排好了就打印beginwriteln(ans);exit;end;for i:=1 to l do//檢測每一個字母if f[i]=false then//若第i個字母未用過beginf[i]:=true;//標記此字母已使用dfs(dep+1,ans+str[i]);{將str第i字母選為第dep個字母,再選下一個}f[i]:=false;//返回時將已用過的字母“還掉”不用了end;end;beginreadln(str);l:=length(str);fillchar(f,sizeof(f),0);//標記每個字母都未用過dfs(1,);end.
快速排序的基本思想就是從一個數(shù)組中任意挑選一個元素(通常來說會選擇最左邊的元素)作為中軸元素,將剩下的元素以中軸元素作為比較的標準,將小于等于中軸元素的放到中軸元素的左邊,將大于中軸元素的放到中軸元素的右邊。
然后以當前中軸元素的位置為界,將左半部分子數(shù)組和右半部分子數(shù)組看成兩個新的數(shù)組,重復上述操作,直到子數(shù)組的元素個數(shù)小于等于1(因為一個元素的數(shù)組必定是有序的)。
以下的代碼中會常常使用交換數(shù)組中兩個元素值的Swap方法,其代碼如下
publicstaticvoidSwap(int[] A, inti, intj){
A[i] = A[j];
擴展資料:
快速排序算法 的基本思想是:將所要進行排序的數(shù)分為左右兩個部分,其中一部分的所有數(shù)據(jù)都比另外一 部分的數(shù)據(jù)小,然后將所分得的兩部分數(shù)據(jù)進行同樣的劃分,重復執(zhí)行以上的劃分操作,直 到所有要進行排序的數(shù)據(jù)變?yōu)橛行驗橹埂?
定義兩個變量low和high,將low、high分別設置為要進行排序的序列的起始元素和最后一個元素的下標。 第一次,low和high的取值分別為0和n-1,接下來的每次取值由劃分得到的序列起始元素和最后一個元素的下標來決定。
定義一個變量key,接下來以key的取值為基準將數(shù)組A劃分為左右兩個部分,通 常,key值為要進行排序序列的第一個元素值。 第一次的取值為A[0],以后毎次取值由要劃 分序列的起始元素決定。
從high所指向的數(shù)組元素開始向左掃描,掃描的同時將下標為high的數(shù)組元素依次與劃分基準值key進行比較操作,直到high不大于low或找到第一個小于基準值key的數(shù)組元素,然后將該值賦值給low所指向的數(shù)組元素,同時將low右移一個位置。
如果low依然小于high,那么由low所指向的數(shù)組元素開始向右掃描,掃描的同時將下標為low的數(shù)組元素值依次與劃分的基準值key進行比較操作,直到low不小于high或找到第一個大于基準值key的數(shù)組元素,然后將該值賦給high所指向的數(shù)組元素,同時將high左移一個位置。
重復步驟(3) (4),直到low的植不小于high為止,這時成功劃分后得到的左右兩部分分別為A[low……pos-1]和A[pos+1……h(huán)igh],其中,pos下標所對應的數(shù)組元素的值就是進行劃分的基準值key,所以在劃分結(jié)束時還要將下標為pos的數(shù)組元素賦值 為 key。
參考資料:快速排序算法_網(wǎng)絡百科
內(nèi)容聲明:
1、本站收錄的內(nèi)容來源于大數(shù)據(jù)收集,版權(quán)歸原網(wǎng)站所有!
2、本站收錄的內(nèi)容若侵害到您的利益,請聯(lián)系我們進行刪除處理!
3、本站不接受違法信息,如您發(fā)現(xiàn)違法內(nèi)容,請聯(lián)系我們進行舉報處理!
4、本文地址:http://m.hudongshop.com/article/e1202a101487057780eb.html,復制請保留版權(quán)鏈接!
body,font,family,Arial,sans,serif,font,size,16px,line,height,1.5,h1,h2,h3,font,weight,bold,h1,font,size,24px,h2,font,size,20px,h3,font,size,18px,code,background,co...。
最新資訊 2024-09-26 23:30:44
引言NullPointerException,NPE,是Java程序中最常見的運行時異常之一,它可能導致不可預測的行為,從輕微的中斷到嚴重的系統(tǒng)故障,NPE的本質(zhì)在于訪問一個未初始化或被顯式設置為null的對象引用,理解NPE及其潛在影響對于編寫穩(wěn)定可靠的Java代碼至關重要,NPE的成因和診斷NPE發(fā)生在以下情況下,試圖調(diào)用或訪問未...。
最新資訊 2024-09-26 15:11:29
簡介JSONDecode是一個Python內(nèi)置函數(shù),用于從JSON字符串解析并創(chuàng)建Python對象,它提供了一個便捷的方法,允許我們輕松地處理JSON數(shù)據(jù),該數(shù)據(jù)在數(shù)據(jù)交換和存儲中無處不在,函數(shù)語法```pythonjson.JSONDecodeError,msg,doc,pos,```msg,錯誤消息的文本描述,doc,要解析的JS...。
技術(shù)教程 2024-09-24 07:09:12
Node.js簡介Node.js是一個基于ChromeV8引擎構(gòu)建的跨平臺JavaScript運行時環(huán)境,它使開發(fā)人員能夠使用JavaScript編寫服務器端應用程序,從而消除了前端和后端之間的語言障礙,全棧開發(fā)的好處全棧開發(fā)是一種軟件開發(fā)方法,其中開發(fā)人員負責應用程序的完整堆棧,從前端到后端,使用Node.js進行全棧開發(fā)具有以下好...。
最新資訊 2024-09-16 11:14:06
p>,以下代碼示例演示如何還原MySQL數(shù)據(jù)庫,mysql,uroot,pCREATEDATABASEIFNOTEXISTSmy,restored,db,USEmy,restored,db,SOURCE,path,to,my,backup.sql,PostgreSQL數(shù)據(jù)庫還原以下代碼示例演示如何還原PostgreSQL數(shù)據(jù)庫,p...。
最新資訊 2024-09-13 06:43:54
簡介ROW函數(shù)可用于從數(shù)據(jù)表中提取特定行的數(shù)據(jù),它還可以自動更新序號,即使在刪除行之后亦是如此,此功能對于保持數(shù)據(jù)表中數(shù)據(jù)的完整性和準確性非常有用,語法```ROW,```其中,``是要提取數(shù)據(jù)的行的序號,示例假設我們有一個名為Students的數(shù)據(jù)表,其中包含以下數(shù)據(jù),ID,姓名,年齡,1,JohnS...。
本站公告 2024-09-13 04:31:37
簡介rate函數(shù)是JavaScript中一個非常有用的函數(shù),它允許我們以每秒的幀率,F(xiàn)PS,執(zhí)行動畫,這使得創(chuàng)建平滑、流暢的動畫變得非常容易,語法rate函數(shù)的語法如下,```rate,framesPerSecond,```其中framesPerSecond是要執(zhí)行動畫的幀率,F(xiàn)PS,基本用法要使用rate函數(shù),我們只需要傳入所需的...。
互聯(lián)網(wǎng)資訊 2024-09-13 03:28:13
Linux定時任務Linux定時任務是一種強大的機制,允許用戶安排在特定時間或定期執(zhí)行任務,它通常用于自動化任務,例如備份、系統(tǒng)維護或其他需要在特定時間或間隔執(zhí)行的任務,創(chuàng)建定時任務要創(chuàng)建定時任務,可以使用crontab命令,crontab是一個文本文件,包含要安排執(zhí)行的任務列表,它可以由用戶編輯,每個用戶都有自己的crontab文件...。
最新資訊 2024-09-12 11:34:46
對于現(xiàn)代企業(yè)而言,數(shù)據(jù)庫是至關重要的資產(chǎn),它們存儲關鍵數(shù)據(jù),為組織的決策和運營提供動力,隨著數(shù)據(jù)量的不斷增長和復雜性的提高,企業(yè)需要創(chuàng)新數(shù)據(jù)庫設計來保持競爭力,尖端的工具正在不斷涌現(xiàn),為數(shù)據(jù)庫設計師提供新的方法來設計和管理數(shù)據(jù)庫,這些工具可以幫助提高生產(chǎn)力、優(yōu)化性能并確保數(shù)據(jù)的完整性,尖端數(shù)據(jù)庫設計工具以下是一些最尖端的數(shù)據(jù)庫設計工具...。
本站公告 2024-09-11 11:21:56
隨著技術(shù)不斷發(fā)展,編程語言也不斷更新,為了在不斷變化的就業(yè)市場中保持領先地位,掌握最熱門的編程語言至關重要,在2013年,以下編程語言處于領先地位,1.PythonPython以其易學、用途廣泛而聞名,在數(shù)據(jù)科學、機器學習和Web開發(fā)等領域得到了廣泛應用,它的簡單語法和豐富的庫使開發(fā)人員能夠快速有效地構(gòu)建項目,Python的使用在近年...。
最新資訊 2024-09-10 15:38:18
Unix操作系統(tǒng)及其廣泛的工具和庫是一套強大的資源,可以幫助程序員編寫復雜且高效的程序,通過利用Unix的功能,程序員可以創(chuàng)建可移植、可定制和可擴展的解決方案,本文將探討如何充分利用Unix工具和庫進行高級編程,幫助您提升編程技能并開發(fā)更出色的應用程序,引言Unix是一個多用戶、多任務操作系統(tǒng),它因其穩(wěn)定性、可靠性和可移植性而聞名,U...。
最新資訊 2024-09-08 07:27:30
在輪回轉(zhuǎn)世和靈魂不滅的觀念中,借尸還魂一直是一個頗具爭議的話題,近年來,隨著科學技術(shù)的進步,關于靈魂輪回轉(zhuǎn)世的研究也取得了一些進展,由于缺乏確鑿的證據(jù),這一領域仍然存在著諸多爭論,朱秀華案件2007年,中國湖南省發(fā)生了一起震驚全國的借尸還魂案件,引發(fā)了關于靈魂輪回轉(zhuǎn)世的激烈討論,該案件的主人公名叫朱秀華,是一位來自農(nóng)村的年輕女子,據(jù)家...。
互聯(lián)網(wǎng)資訊 2024-09-05 04:31:16