Task 03:數(shù)組排序(day2)

Task 03: 數(shù)組排序

第5天打卡,附上學習鏈接

1 學習內容

1.1 希爾排序(Shell Sort)

將整個序列按照一定的間隔取值劃分為若干個子序列,每個子序列分別進行插入排序,然后逐漸縮小間隔進行下一輪劃分子序列和插入排序,直至最后一輪排序間隔為1,對整個序列進行插入排序。

算法步驟:

  • (1)首先確定一個元素間隔數(shù)gap,然后將參與排序的序列按此間隔數(shù)從第1個元素開始一次劃分成若干個子序列,即分別將所有位置相隔為gap的元素視為一個子序列,在各個子序列中采用某種排序方法進行插入排序;

  • (2)然后減少間隔數(shù),并重新將整個序列按新的間隔數(shù)劃分為若干個子序列,再分別對各個子序列進行排序,如此下去,直到間隔數(shù)gap=1。

算法分析:

  • 希爾排序方法的速度是一系列間隔數(shù)gapi的函數(shù);

  • 不穩(wěn)定排序算法

  • 因為每次都除以2,向下取整的方式縮小間隔數(shù),對有n個元素的序列,若gap1=floor(n/2),則經過log2n趟排序后就有gapp=1,所以謝爾排序方法的排序總趟數(shù)為floor(log2n);

  • 最外層的while循環(huán)為log2n數(shù)量級,中間層do-while循環(huán)為n數(shù)量級。當子序列分的越多,子序列中的元素越少,最內層的for循環(huán)的次數(shù)也就越少;反之當分的越少,子序列的元素也隨之增多,但整個序列也逐步有序,而循環(huán)次數(shù)卻不會隨之增加。因此,希爾排序算法的時間復雜度在O(nlog2n)與O(n2)之間。

代碼實現(xiàn):

def shellSort(arr):
 size = len(arr)
 gap = size // 2

 while gap > 0:
 for i in range(gap, size):
 temp = arr[i]
 j = i
 while j >= gap and arr[j-gap] > temp:
 arr[j] = arr[j-gap]
 j -= gap
 arr[j] = temp
 gap = gap // 2
 return arr
1.2 歸并排序(Merge Sort)

采用經典的分治策略,先遞歸地將當前序列平均分為兩半,然后將有序序列兩兩合并,最終合并成一個有序序列。

算法步驟:

  • (1)初始時,將待排序的序列中的n個記錄看成n個有序子序列,每個子序列的長度均為1;

  • (2)把當前序列組中有序子序列兩兩歸并,完成一遍之后序列組里的排序序列個數(shù)減半,每個子序列的長度加倍;

  • (3)對長度加倍的有序子序列重復以上操作,最終得到一個長度為n的有序序列。

算法分析:

  • 歸并排序算法的時間復雜度等于歸并趟數(shù)與每一趟歸并的時間復雜度成績。子算法merge(left_arr, right_arr):時間復雜度為O(n),因此歸并排序算法總的時間復雜度為O(nlog2n);

  • 歸并排序方法需要用到與參加排序的序列同樣大小的輔助空間,所以空間復雜度為O(n);

  • 因為在兩個有序子序列的歸并過程中,如果兩個有序序列中出現(xiàn)相同元素,merge(left_arr, right_arr):算法能夠使前一個序列中那個相同元素先被復制,從而確保這兩個元素的相對次序不發(fā)生改變,所以是穩(wěn)定排序算法。

代碼實現(xiàn):

def merge(left_arr, right_arr):
    arr = []
    while left_arr and right_arr:
        if left_arr[0] <= right_arr[0]:
            arr.append(left_arr.pop(0))
        else:
            arr.append(right_arr.pop(0))
            
    while left_arr:
        arr.append(left_arr.pop(0))
    while right_arr:
        arr.append(right_arr.pop(0))
    return arr

def mergeSort(arr):
    size = len(arr)
    if size < 2:
        return arr
    mid = len(arr) // 2
    left_arr, right_arr = arr[0:mid], arr[mid:]
    return merge(mergeSort(left_arr), mergeSort(right_arr))

2 練習題目

2.1 0506 相對名次 *

題目描述:給出N名運動員的成績,找出他們的相對名次并授予前三名對應的獎牌。前三名運動員將會被分別授予”金牌“,”銀牌“和”銅牌"("Gold Medal", "Silver Medal", ”Bronze Medal“),注:分數(shù)越高的選手,排名越靠前。所有運動員的成績都不相同。 樣例1:輸入為[5, 4, 3, 2, 1],輸出為["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"]。

解題思路:先實現(xiàn)降序排列,然后構建分數(shù)和名詞的字典,最后根據(jù)原score找出結果即可。

class Solution:
    def findRelativeRanks(self, score: List[int]) -> List[str]:
        score_sort = sorted(score, reverse=True)
        rank_list = ["Gold Medal", "Silver Medal",
                     "Bronze Medal"]+[str(i+4) for i in range(len(score)-3)]
        dic = dict(zip(score_sort, rank_list))
        res = [dic.get(i) for i in score]
        return res
2.2 面試題 10.01 合并排序的數(shù)組 **

題目描述:給定兩個排序后的數(shù)組A和B,其中A的末端有足夠的緩沖空間容納B。編寫一個方法,將B合并入A并排序。初始化A和B的元素數(shù)量分別為m和n。 樣例1:輸入為A=[1, 2, 3, 0, 0, 0], m=3, B=[2, 5, 6], n=3,輸出為[1, 2, 2, 3, 5, 6]。

解題思路:先將數(shù)組B放進數(shù)組A的尾部,然后直接對整個數(shù)組進行排序。

class Solution:
    def merge(self, A: List[int], m: int, B: List[int], n: int) -> None:
        """
        Do not return anything, modify A in-place instead.
        """
        A[m:] = B
        A.sort()

時間復雜度:O((m+n)log(m+n)); 空間復雜度:O(log(m+n))。

雙指針的思想 妙呀
將兩個數(shù)組看作隊列,每次從兩個隊列頭部取出較小的數(shù)字放入結果。

class Solution:
    def merge(self, A: List[int], m: int, B: List[int], n: int) -> None:
        """
        Do not return anything, modify A in-place instead.
        """
        sorted = []
        pa, pb = 0, 0  # 使用pa和pb來作為隊列的頭部指針
        while pa < m or pb < n:
            if pa == m:
                sorted.append(B[pb])
                pb += 1
            elif pb == n:
                sorted.append(A[pa])
                pa += 1
            elif A[pa] < B[pb]:
                sorted.append(A[pa])
                pa += 1
            else:
                sorted.append(B[pb])
                pb += 1
         A[:] = sorted

時間復雜度:O(m+n); 空間復雜度:O(m+n)。

2.3 劍指Offer 51 數(shù)組中的逆序對 ***

題目描述:在數(shù)組中的兩個數(shù)字,如果前面一個數(shù)字大于后面的數(shù)字,則這兩個數(shù)字組成一個逆序對。輸入一個數(shù)組,求出這個數(shù)組中的逆序對的總數(shù)。 樣例1:輸入為[7, 5, 6, 4],輸出為5。

解題思路:思考中。。。。理不清。。。。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容