1. 程式人生 > 其它 >python-排序 冒泡和快速排序

python-排序 冒泡和快速排序

交換排序

  交換排序有氣泡排序和快速排序

氣泡排序

  氣泡排序就是每次找出最大(最小)元素,放在集合最前或最後,這是最簡單的排序演算法

def bubble_sort(collection):
    #升序排列
    length=len(collection)
    for s in range(length-1):#可以假設只有一個元素的情況,這樣可以直接返回
        flage=True#應該放在這裡,而不是上面
        for i in range(length-1-s):
            if collection[i]>collection[i+1]:#前者大需要換位置,並需要判斷他是否是最大的
                flage=False
                collection[i],collection[i+1]=collection[i+1],collection[i]
        # print("排序第",s+1,"輪之後:",collection)#print()好佔時間啊
        # i++#i是自動遞增的,我竟然寫出如此愚蠢的
        if flage:
            break
    return collection

  特點:是穩定的 T(n)=O(n^2) 原地排序

  內層迴圈的操作是O(1)的,共執行n-1輪迴圈,每輪分別執行(n-1,n-2....1)=(n-1)(n-1+1)/2

快速排序

  效率:

  

  演算法思想:分治法

  快速排序是對氣泡排序的一種改進,氣泡排序作為一種廣為人知的最簡單的排序演算法,存在著很多不足,比如他每趟遍歷後只能從當前數列中挑出一個最大(最小)的數值,然後下趟工作再挑出剩下中的最大元素。這樣看來,每趟之間幾乎是完全獨立的,這一趟的排序除了能使帶排序的元素減少一個之外,並不會留下任何資訊。這很明顯就浪費了這一趟又一趟的比較。完全可以從一趟一趟中瞭解關於帶排序的樣本的更多資訊。

  快速排序就是另外一種思路,他最明顯的特點就是“分而治之”。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列

  快速排序版本1

  特點:需要額外的空間用來存放兩個陣列(一個比比較點大的,一個比比較點小的)、不需要兩個遊標,從前往後遍歷就行

def quick_sort3(collection):
    length=len(collection)
    if length<=1:
        return collection
    else:
        pivot=collection[0]
        greater=[]#學會接受這樣每當遞迴中定義變數,並不複雜
        lesser=[]
        for i in collection[1:]:
            greater.append(i) if i>=pivot else lesser.append(i)
        return quick_sort3(lesser)+[pivot]+quick_sort3(greater)

  這個是穩定排序、需要額外的空間、時間複雜度是

  快速排序版本2

  另一種廣為流傳的思想是選擇兩個遊標,遊標是移動的,在初始化的時候,我們一般將陣列元素的第一個和最後一個元素(注意,代表的陣列地址,會移動),然後他們兩個交替的向前或者向後移動,每次移動一個元素,然後與一個值比較(直到找到為止並不是一次移動一個),(並不會讓他們兩個相互比較,)我們習慣上將這個值稱為key,這個值初始化為陣列首元素。

  在比較的過程中,由於兩個遊標(一個i,一個j)是交替移動的,所以他們必然有相遇的時候,我將每次相遇,看作為一輪比較的結束,這一輪會將待排序的陣列分為3個部分,一個部分只有key,另外兩個部分分別存放比key小和比key大的元素。這就是分而治之的結果,除了只有一個元素的結果,下一次的分治過程又會從他們裡面開始。

  每一輪中的比較結果首先從i或j與key的比較開始,是i還是j怎樣都行。我只需要記住,比較是為了將結果向有序的升序(或者降序)去靠攏。每一輪都是為了減小顆粒度。拿升序來說,如果i代表的下標所指的陣列元素比key大,那麼他就應該和j交換,如果沒有就向後移動一次,然後換j與key比較,如果j比key小,j和i就交換。

def quick_sort3(collection):
    length=len(collection)
    if length<=1:
        return collection
    else:
        pivot=collection[0]
        key=0
        i=0
        j=length-1
        while i<j:
            while collection[j]>pivot:
                j-=1
            if(i<j):
                collection[key],collection[j]=collection[j],collection[key]
                key=j
            while collection[i]<pivot:
                i+=1
            if i<j:
                collection[i],collection[key]=collection[key],collection[i]
                key=i
        return quick_sort3(collection[:key])+[collection[key]]+quick_sort3(collection[key+1:])

  原地排序、時間複雜度不會算一趟的演算法複雜度是N,然後大約需要logN次遞迴,所以時間複雜度是NlogN、空間複雜度是logN,每次需要一個嘛

  資料越隨機分佈時,快速排序效能越好;資料越接近有序,快速排序效能越差

  快速排序版本2 修改

  上面的快速排序在正常排序時時沒有問題的,不過當遇到有大量重複的元素,而且元素為key的時候,就會造成排序失敗

def quick_sort3(collection):
    length=len(collection)
    if length<=1:
        return collection
    else:
        pivot=collection[0]
        key=0
        i=0
        j=length-1
        repeat=[]#將重複的元素添入,只有大量的key重複的時候才會出錯
        while i<j:#外層while負責讓i,j一直移位,內層迴圈保證找到要交換的值,然後分為兩個while,這樣,i,j能交替執行
            while collection[j]>=pivot:
                if collection[j]==pivot and j!=key:
                    repeat.append(collection.pop(j))
                    # key-=1#因為此時key永遠等於i的
                    #判斷j!=key
                if j>0:
                    j-=1
                else:
                     return collection 
            if(i<j):
                collection[i],collection[j]=collection[j],collection[i]
                key=j
            while collection[i]<=pivot:
                if collection[i]==pivot and i!=key:
                    repeat.append(collection.pop(i))
                    j-=1#因為少了一個元素,j在後邊
                    key-=1
                    # if i<length-1:因為j後面的都被幹掉了
                    #     continue
                    # else:
                    #     i-=1
                if i<length-1:
                    i+=1 
                else:
                    return collection
            if i<j:
                collection[i],collection[j]=collection[j],collection[i]
                key=i
        repeat.append(collection[key])
        return quick_sort3(collection[:key])+repeat+quick_sort3(collection[key+1:])              

  

  四不像版本

def quick_sort(collection):
    length=len(collection)
    i=0
    j=length-1
    if(length>1):
        key=collection[0]
        logging.info("新一輪的排序開始了i,j,key的值分別為",i,j,key,"被排序的陣列是:",collection,'此次被排序陣列的長度是:',length)
        while(i<j):
            logging.info('先輸出i=%s  j=%s'%(i,j))
            while(collection[j]>key):
                j=j-1    
            collection[i],collection[j]=collection[j],collection[i]
            logging.info('*'*25+'又經過了一次j交換,交換的陣列下標j的值為',j,'這時的陣列為',collection)
            while(collection[i]<key):
                i=i+1
            collection[i],collection[j]=collection[j],collection[i]#正是這一句導致了重複定位ij的結果,因為即使上面的while
            #起了作用,這句也會執行的。
            logging.info('*'*25+'又經過了一次i交換,交換的陣列下標i的值為',i,'這時的陣列為',collection)
        logging.info("這一輪過後key兩邊的陣列是:"+' '*53,collection[0:i],'[',key,']',collection[i+1:length],'整個陣列為:',collection,'\n')#要加逗號啦
        # L.extend(collection)
        #遞迴
        if(i>0):#是這裡的問題,之前的i=0了因為陣列的第一個元素是最小的就會出現這樣的情況
            # print('現在的L是:',L)
            logging.info('對%s的左邊排序'%(key))
            logging.info('%s左邊返回的結果是'%(key),quick_sort(collection[0:i]),'key是',key)
            L.append(key)#這裡也是哦,不必擔心遞迴的原因會不會新增錯,應該這樣想,正是因為遞迴的原因,才保證了新增的順序
            #性,因為這裡也算是在方法體中嘛。
            # s=quick_sort(collection[0:i])
            # if(s!=-1):
            #     L.extend(s)
            # L.append(key)
            # print("儲存了:",s,'key是',key)
        else:
            L.append(key)
            logging.info('%s的左邊沒有元素了'%(key),'向L中新增key,此時L為:',L)
        if(j+1<length):#為什麼這裡不能寫成elif類,因為這兩個判斷應該是相互獨立的,即在分而治之的過程中,i代表的左邊
            #沒有元素了,然後在處理右邊,如果改成elif,那麼情況就會變成如果i<0了,那麼就會不管右邊了,即判斷
            #右邊需不需要處理的判斷就會只有滿足了第一個條件之後才會進入。
            # print('右邊返回的結果是',quick_sort(collection[j+1:length]))
            logging.info('對%s的右邊進行排序'%(key))
            logging.info('%s右邊返回的結果是'%(key),quick_sort(collection[j+1:length]))
            # s=quick_sort(collection[j+1:length])
            # if(s!=-1):
            #     L.extend(s)
            # print("儲存了:",s)
            # print('現在的L是:',L)
        else:
            logging.info('%s的右邊沒有元素了'%(key))
    # print("此輪被排序的陣列長度為1")
    elif(length>0):
        L.extend(collection)#在這裡新增這個想法真的很棒,雖然是想了好久才想出來這個辦法,但不得不佩服我自己,正是經過了前面的試錯
        #才能讓我想到不需要在遞迴中對結果進行判斷,而是在被呼叫的方法體中,直接找出正確的(即想要的)返回結果去新增。
        return collection#忽略了一點,原以為這裡即使不寫else return也會只有在陣列長度等於1的長度下被返回的,即返回單個數,但實際情況可能不是這樣的。
    logging.info('返回-1代表這裡已經沒有元素了,或許是已經被排序過了或者是原陣列的兩端')
    return -1

  

對比

  採用版本1與選擇排序相比較,資料為隨機資料,大小為1000,執行100次結果差了

詳細資料:[0.07895469666, 0.07895302773, 0.08095312119, 0.08338785172, 0.08293843269, 0.08093643188, 0.08128547668, 0.0819542408, 0.08295297623, 0.08095312119, 0.08395147324, 0.08097147942, 0.082947
01576, 0.08095216751, 0.07995295525, 0.08095240593, 0.0829513073, 0.0809533596, 0.0839509964, 0.0829513073, 0.08095312119, 0.08097696304, 0.08094286919, 0.08095240593, 0.08195757866, 0.08095288277, 0.0809533596, 0.08095407486, 0.07995390892, 0.07995271683, 0.08095264435, 0.08295178413, 0.08395934105, 0.07995295525, 0.08295154572, 0.08195376396, 0.08097577095, 0.08192324638, 0.0809533596, 0.08294081688, 0.08194708824, 0.08295035362, 0.08295178413, 0.08195447922, 0.08295416832, 0.08094596863, 0.08295106888, 0.08195185661, 0.08195209503, 0.08195328712, 0.08095407486, 0.08197164536, 0.08094024658, 0.08195352554, 0.08195328712, 0.0819504261, 0.08195257187, 0.08095240593, 0.08095288277, 0.08095312119, 0.08395195007, 0.08095312119, 0.08195996284, 0.08093881607, 0.08095312119, 0.08494997025, 0.08195304871, 0.08095192909, 0.08195161819, 0.08046650887, 0.08190274239, 0.08197069168, 0.08202648163, 0.08195185661, 0.08094859123, 0.07995486259, 0.08295321465, 0.08095264435, 0.08194589615, 0.08194684982, 0.07995510101, 0.08095288277, 0.07995533943, 0.08095288277, 0.08295106888, 0.08295273781, 0.0799536705, 0.08195281029, 0.08193540573, 0.07994103432, 0.08295202255, 0.08195304871, 0.08095312119, 0.08195400238, 0.08095359802, 0.08195233345, 0.08295321465, 0.08095383644, 0.08095288277, 0.08295273781]
運行了100次,平均執行時間差(me-other)/(bubble-quick)(正數代表你是個弟弟)是:0.08164532900
前者平均執行時間0.08336502552,後者平均執行時間0.00171969652,前者約是後者的48.4766倍

  

  

我的問題

  1)當所有分而治之的結果 的左邊都被排序好了,或者顆粒度是最小的,那麼右邊的就不排了。換句話說,剩下的所有工作都不去做了。

(sort) λ python bubble_sort.py
未排序之前:      [70, 78, 85, 10, 66, 43, 89, 62, 11, 41]
key兩邊的陣列是: [41] [ 70 ] [85, 10, 66, 43, 89, 62, 11, 78]
*************************i,j的值分別為 1 9
key兩邊的陣列是: [41, 11] [ 70 ] [10, 66, 43, 89, 62, 85, 78]
*************************i,j的值分別為 2 8
key兩邊的陣列是: [41, 11, 62, 10, 66, 43] [ 70 ] [89, 85, 78]
*************************i,j的值分別為 6 7
key兩邊的陣列是: [41, 11, 62, 10, 66, 43] [ 70 ] [89, 85, 78]
*************************i,j的值分別為 6 6
key兩邊的陣列是: [10, 11] [ 41 ] [62, 66, 43]
*************************i,j的值分別為 2 3
key兩邊的陣列是: [10, 11] [ 41 ] [62, 66, 43]
*************************i,j的值分別為 2 2
key兩邊的陣列是: [] [ 10 ] [11]
*************************i,j的值分別為 0 0
key兩邊的陣列是: [] [ 41 ] [62, 66, 43]
*************************i,j的值分別為 0 0
key兩邊的陣列是: [] [ 70 ] [89, 85, 78]
*************************i,j的值分別為 0 0
排序之後: [41, 11, 62, 10, 66, 43, 70, 89, 85, 78]
耗費時間: 0.023987293243408203

  2)為什麼第二趟都從0開始啊

  解決辦法:這個不是程式的原因,而是因為程式遞迴到第二次時,穿過去的陣列中指定的key就是最小的了。   

未排序之前:                                                                     [6, 5, 4, 8, 7, 9, 3, 2, 1]
*************************又經過了一次j交換,交換的陣列下標j的值為 8 這時的陣列為 [1, 5, 4, 8, 7, 9, 3, 2, 6]
*************************又經過了一次i交換,交換的陣列下標i的值為 3 這時的陣列為 [1, 5, 4, 6, 7, 9, 3, 2, 8]
*************************又經過了一次j交換,交換的陣列下標j的值為 7 這時的陣列為 [1, 5, 4, 2, 7, 9, 3, 6, 8]
*************************又經過了一次i交換,交換的陣列下標i的值為 4 這時的陣列為 [1, 5, 4, 2, 6, 9, 3, 7, 8]
*************************又經過了一次j交換,交換的陣列下標j的值為 6 這時的陣列為 [1, 5, 4, 2, 3, 9, 6, 7, 8]
*************************又經過了一次i交換,交換的陣列下標i的值為 5 這時的陣列為 [1, 5, 4, 2, 3, 6, 9, 7, 8]
*************************又經過了一次j交換,交換的陣列下標j的值為 5 這時的陣列為 [1, 5, 4, 2, 3, 6, 9, 7, 8]
*************************又經過了一次i交換,交換的陣列下標i的值為 5 這時的陣列為 [1, 5, 4, 2, 3, 6, 9, 7, 8]
這一輪過後key兩邊的陣列是:                                                      [1, 5, 4, 2, 3] [ 6 ] [9, 7, 8]
*************************又經過了一次j交換,交換的陣列下標j的值為 0 這時的陣列為 [1, 5, 4, 2, 3]
*************************又經過了一次i交換,交換的陣列下標i的值為 0 這時的陣列為 [1, 5, 4, 2, 3]
這一輪過後key兩邊的陣列是:                                                      [] [ 1 ] [5, 4, 2, 3]
*************************又經過了一次j交換,交換的陣列下標j的值為 0 這時的陣列為 [6, 9, 7, 8]
*************************又經過了一次i交換,交換的陣列下標i的值為 0 這時的陣列為 [6, 9, 7, 8]
這一輪過後key兩邊的陣列是:                                                      [] [ 6 ] [9, 7, 8]
排序之後: [1, 5, 4, 2, 3, 6, 9, 7, 8] L: [1, 5, 4, 2, 3, 6, 9, 7, 8]

  第一次版本,失敗了

def quick_sort(collection):
    length=len(collection)
    i=0
    j=length-1
    if(length>1):
        key=collection[0]
        print("新一輪的排序開始了i,j,key的值分別為",i,j,key,"被排序的陣列是:",collection,'此次被排序陣列的長度是:',length)
        while(i<j):
            while(collection[j]>key):
                j=j-1    
            collection[i],collection[j]=collection[j],collection[i]
            print('*'*25+'又經過了一次j交換,交換的陣列下標j的值為',j,'這時的陣列為',collection)
            while(collection[i]<key):
                if(i<j):
                    i=i+1
                break
            collection[i],collection[j]=collection[j],collection[i]
            print('*'*25+'又經過了一次i交換,交換的陣列下標i的值為',i,'這時的陣列為',collection)
        print("這一輪過後key兩邊的陣列是:"+' '*53,collection[0:i],'[',key,']',collection[i+1:length],'整個陣列為:',collection,'\n')#要加逗號啦
        # L.extend(collection)
        #遞迴
        if(i>0):
            # print('現在的L是:',L)
            print('對%s的左邊排序'%(key))
            print('%s左邊返回的結果是'%(key),quick_sort(collection[0:i]),'key是',key)
            # s=quick_sort(collection[0:i])
            # if(s!=-1):
            #     L.extend(s)
            # L.append(key)
            # print("s是:",s,'key是',key)
        if(j>0):#為什麼這裡不能寫成elif類,因為這兩個判斷應該是相互獨立的,即在分而治之的過程中,i代表的左邊
            #沒有元素了,然後在處理右邊,如果改成elif,那麼情況就會變成如果i<0了,那麼就會不管右邊了,即判斷
            #右邊需不需要處理的判斷就會只有滿足了第一個條件之後才會進入。
            # print('右邊返回的結果是',quick_sort(collection[j+1:length]))
            print('對%s的右邊進行排序'%(key))
            print('%s右邊返回的結果是'%(key),quick_sort(collection[j+1:length]))
            # s=quick_sort(collection[j+1:length])
            # if(s!=-1):
            #     L.extend(s)
            # print("s是:",s)
            # print('現在的L是:',L)
    # print("此輪被排序的陣列長度為1")
    elif(length>0):
        return collection#忽略了一點,原以為這裡即使不寫else return也會只有在陣列長度等於1的長度下被返回的,即返回單個數,但實際情況可能不是這樣的。
    print('這裡已經沒有元素了')
    return -1



#產生排序陣列
# collection=random.sample(range(1,100),10)
# collection =[6,5,4,8,7,9,3,1,2]
collection= [94, 37, 97, 31, 26, 79, 10, 35, 40, 6]
startTime=time.time()
print("未排序之前:"+' '*68,collection)#不能寫成+(會提示為不是str型別資料,要寫成這樣)
print("排序之後:",quick_sort(collection),'L:',L)
endTime=time.time()
print("耗費時間:",endTime-startTime)

  失敗的原因是:

未排序之前:                                                                     [94, 37, 97, 31, 26, 79, 10, 35, 40, 6]
新一輪的排序開始了i,j,key的值分別為 0 9 94 被排序的陣列是: [94, 37, 97, 31, 26, 79, 10, 35, 40, 6] 此次被排序陣列的長度是: 10
*************************又經過了一次j交換,交換的陣列下標j的值為 9 這時的陣列為 [6, 37, 97, 31, 26, 79, 10, 35, 40, 94]
*************************又經過了一次i交換,交換的陣列下標i的值為 1 這時的陣列為 [6, 94, 97, 31, 26, 79, 10, 35, 40, 37]
*************************又經過了一次j交換,交換的陣列下標j的值為 9 這時的陣列為 [6, 37, 97, 31, 26, 79, 10, 35, 40, 94]
*************************又經過了一次i交換,交換的陣列下標i的值為 2 這時的陣列為 [6, 37, 94, 31, 26, 79, 10, 35, 40, 97]
*************************又經過了一次j交換,交換的陣列下標j的值為 8 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 35, 94, 97]
*************************又經過了一次i交換,交換的陣列下標i的值為 3 這時的陣列為 [6, 37, 40, 94, 26, 79, 10, 35, 31, 97]
*************************又經過了一次j交換,交換的陣列下標j的值為 8 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 35, 94, 97]
*************************又經過了一次i交換,交換的陣列下標i的值為 4 這時的陣列為 [6, 37, 40, 31, 94, 79, 10, 35, 26, 97]
*************************又經過了一次j交換,交換的陣列下標j的值為 8 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 35, 94, 97]
*************************又經過了一次i交換,交換的陣列下標i的值為 5 這時的陣列為 [6, 37, 40, 31, 26, 94, 10, 35, 79, 97]
*************************又經過了一次j交換,交換的陣列下標j的值為 8 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 35, 94, 97]
*************************又經過了一次i交換,交換的陣列下標i的值為 6 這時的陣列為 [6, 37, 40, 31, 26, 79, 94, 35, 10, 97]
*************************又經過了一次j交換,交換的陣列下標j的值為 8 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 35, 94, 97]
*************************又經過了一次i交換,交換的陣列下標i的值為 7 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 94, 35, 97]
*************************又經過了一次j交換,交換的陣列下標j的值為 8 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 35, 94, 97]
*************************又經過了一次i交換,交換的陣列下標i的值為 8 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 35, 94, 97]
這一輪過後key兩邊的陣列是:                                                      [6, 37, 40, 31, 26, 79, 10, 35] [ 94 ] [97] 整個陣列為: [6, 37, 40, 31, 26, 79, 10, 35, 94, 97]

對94的左邊排序
新一輪的排序開始了i,j,key的值分別為 0 7 6 被排序的陣列是: [6, 37, 40, 31, 26, 79, 10, 35] 此次被排序陣列的長度是: 8
*************************又經過了一次j交換,交換的陣列下標j的值為 0 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 35]
*************************又經過了一次i交換,交換的陣列下標i的值為 0 這時的陣列為 [6, 37, 40, 31, 26, 79, 10, 35]
這一輪過後key兩邊的陣列是:                                                      [] [ 6 ] [37, 40, 31, 26, 79, 10, 35] 整個陣列為: [6, 37, 40, 31, 26, 79, 10, 35]#這裡該向下遞迴的沒有遞迴

這裡已經沒有元素了
94左邊返回的結果是 -1 key是 94
對94的右邊進行排序
94右邊返回的結果是 [97]
這裡已經沒有元素了
排序之後: -1 L: []
耗費時間: 0.008994817733764648

  我猜想可能是因為對左邊或右邊進行排序的時候沒有響應的判斷邏輯。

3)修正

while(i<j):#這裡不應該是i<j-1,即使這樣能避免有些交換陣列下標的重複,但會產生下面的問題,當排序三個元素的陣列中key為中間值時,會忽略右邊的元素。
            print('先輸出i=%s  j=%s'%(i,j))
            while(collection[j]>key):
                j=j-1    
            collection[i],collection[j]=collection[j],collection[i]
            print('*'*25+'又經過了一次j交換,交換的陣列下標j的值為',j,'這時的陣列為',collection)
            while(collection[i]<key):
                i=i+1
            collection[i],collection[j]=collection[j],collection[i]#正是這一句導致了重複定位ij的結果,因為即使上面的while
            #起了作用,這句也會執行的。
            print('*'*25+'又經過了一次i交換,交換的陣列下標i的值為',i,'這時的陣列為',collection)


新一輪的排序開始了i,j,key的值分別為 0 2 4 被排序的陣列是: [4, 5, 3] 此次被排序陣列的長度是: 3
先輸出i=0  j=2
*************************又經過了一次j交換,交換的陣列下標j的值為 2 這時的陣列為 [3, 5, 4]
*************************又經過了一次i交換,交換的陣列下標i的值為 1 這時的陣列為 [3, 4, 5]
先輸出i=1  j=2
*************************又經過了一次j交換,交換的陣列下標j的值為 1 這時的陣列為 [3, 4, 5]
*************************又經過了一次i交換,交換的陣列下標i的值為 1 這時的陣列為 [3, 4, 5]
這一輪過後key兩邊的陣列是:                                                      [3] [ 4 ] [5] 整個陣列為: [3, 4, 5]

對4的左邊排序
4左邊返回的結果是 [3] key是 4
對4的右邊進行排序
4右邊返回的結果是 [5]
這裡已經沒有元素了
2右邊返回的結果是 -1
這裡已經沒有元素了
6左邊返回的結果是 -1 key是 6
對6的右邊進行排序