Python 快速排序法(轉)


方法解讀:

例:對初始序列:“6  1  2 7  9  3  4  5 10  8”采用快速排序法:

一、分別從初始序列“6  1  2 7  9  3  4  5 10  8”兩端開始“探測”。

從右往左找一個小於6的數,再從左往右找一個大於6的數,然后交換他們

這里可以用兩個變量 i j ,分別指向序列最左邊和最右邊。

我們為這兩個變量起個好聽的名字“哨兵i”和“哨兵j”。

剛開始的時候讓 哨兵i 指向序列的最左邊(即i=1),指向數字6

讓 哨兵j 指向序列的最右邊(即j=10),指向數字8

 二、首先 哨兵j 開始出動。

因為此處設置的基准數是最左邊的數,所以需要讓哨兵j先出動,這一點非常重要(請自己想一想為什么)。

哨兵j 一步一步地向左挪動(即 j--),直到找到一個小於6的數停下來。

接下來 哨兵i 再一步一步向右挪動(即 i++),直到找到一個數大於6的數停下來。

最后 哨兵j 停在了數字5面前,哨兵i 停在了數字7面前。

現在交換 哨兵i哨兵j 所指向的元素的值。

到此,第一次交換結束。

三、接下來開始 哨兵j 繼續向左挪動(再友情提醒,每次必須是 哨兵j 先出發)。

他發現了4(比基准數6要小,滿足要求)之后停了下來。

哨兵i 也繼續向右挪動的,他發現了9(比基准數6要大,滿足要求)之后停了下來。

此時再次進行交換。

四、第二次交換結束,“探測”繼續。
哨兵j 繼續向左挪動,他發現了3(比基准數6要小,滿足要求)之后又停了下來。
哨兵i 繼續向右移動,糟啦!此時 哨兵i哨兵j 相遇了, 哨兵i哨兵j 都走到3面前。
說明此時“探測”結束。
我們將基准數6和3進行交換。交換之后的序列如下。

五、  到此第一輪“探測”真正結束。

此時以基准數6為分界點,6左邊的數都小於等於6,6右邊的數都大於等於6。

回顧一下剛才的過程,其實 哨兵j 的使命就是要找小於基准數的數,而 哨兵i 的使命就是要找大於基准數的數,直到 i j 碰頭為止。

現在基准數6已經歸位,它正好處在序列的第6位。
此時我們已經將原來的序列,以6為分界點拆分成了兩個序列,左邊的序列是“3  1 2  5  4”,右邊的序列是“9  7  10  8”。
接下來還需要分別處理這兩個序列。因為6左邊和右邊的序列目前都還是很混亂的。
不過不要緊,我們已經掌握了方法,接下來只要模擬剛才的方法分別處理6左邊和右邊的序列即可。
六、現在先來處理6左邊的序列現吧。
左邊的序列是“3  1  2 5  4”。請將這個序列以3為基准數進行調整,使得3左邊的數都小於等於3,3右邊的數都大於等於3。好了開始動筆吧。
如果你模擬的沒有錯,調整完畢之后的序列的順序應該是。
        2  1  3  5  4
 OK,現在3已經歸位。
接下來需要處理3左邊的序列“2 1”和右邊的序列“5 4”。
對序列“2 1”以2為基准數進行調整,處理完畢之后的序列為“1 2”,到此2已經歸位。
序列“1”只有一個數,也不需要進行任何處理。至此我們對序列“2 1”已全部處理完畢,得到序列是“1 2”。
序列“5 4”的處理也仿照此方法,最后得到的序列如下。
        1  2  3 4  5  6 9  7  10  8
七、對於序列“9  7  10  8”也模擬剛才的過程,直到不可拆分出新的子序列為止。
最終將會得到這樣的序列,如下。
        1  2  3 4  5  6  7  8 9  10
八、到此,排序完全結束。
細心的同學可能已經發現,快速排序的每一輪處理其實就是將這一輪的基准數歸位,直到所有的數都歸位為止,排序就結束了。
下面上個霸氣的圖來描述下整個算法的處理過程。

九、原始網址:https://blog.csdn.net/adusts/article/details/80882649

十、Python程序:

#快速排序法一:有小到大排序

def quickSort(arr,left,right):#arr:待排序的數列;left:數列開始的下標索引;right:數列結束的下標索引

  if left > right:#如果開始索引大於結束索引
    return

  temp=arr[left];#取最左邊的數為 基准數
  i,j=left,right

  while i!= j:#現從右邊開始找
    while arr[j]>=temp and i<j:#當前數值大於基准數
      j-=1

    while arr[i]<=temp and i<j:#當前數值小於基准數
      i+=1

    if i<j:#交換兩個數再數組中的位置
      t=arr[i]
      arr[i]=arr[j]
      arr[j]=t

  #將 基准數 歸位
  arr[left]=arr[i]
  arr[i]=temp

  quickSort(arr,left,i-1)#遞歸:繼續處理左邊的
  quickSort(arr,i+1,right)#遞歸:繼續處理右邊的


#測試
arr=[10,7,8,8,9,1,5]
n=len(arr)
quickSort(arr,0,n-1)
print("排序后的數組:")
for i in range(n):
print("%d" %arr[i])

 

#快速排序法二:由大到小排序

def quickSort(arr,left,right):#arr:待排序的數列;left:數列開始的下標索引;right:數列結束的下標索引

  if left > right:#如果開始索引大於結束索引
    return

  temp=arr[left];#取最左邊的數為 基准數
  i,j=left,right

  while i!= j:#現從右邊開始找
    while arr[j]<=temp and i<j:#當前數值小於基准數
      j-=1

    while arr[i]>=temp and i<j:#當前數值大於基准數
      i+=1

  if i<j:#交換兩個數再數組中的位置
    t=arr[i]
    arr[i]=arr[j]
    arr[j]=t

  #將 基准數 歸位
  arr[left]=arr[i]
  arr[i]=temp

  quickSort(arr,left,i-1)#遞歸:繼續處理左邊的
  quickSort(arr,i+1,right)#遞歸:繼續處理右邊的


#測試
arr=[10,7,8,8,9,1,5]
n=len(arr)
quickSort(arr,0,n-1)
print("排序后的數組:")
for i in range(n):
print("%d" %arr[i])


 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM