分治思維與歸併排序

刷到歸併,就此開坑,歸併似乎用的是分治的思維

👉圖解歸併算法

👉參考詳解 :其中詮釋出,通過分治的方法,降低對比交換的次數,來降低時間複雜度

分治!就是把大問題肢解成同類小問題解決(遞歸)


二分法查詢(用於有序數列)

通過設立center,把長數列中查詢或計數的工作分到每一個部分當中去完成,最後合併(求和)

代碼略


歸併排序

def mergeSort(temp_list, number_list, left, right):
    if left == right:
        return
    elif left < right:
        center = (left + right)//2
        mergeSort(temp_list, number_list, left, center)
        mergeSort(temp_list, number_list, center+1, right)
        merge(temp_list, number_list, left, center, right)

    return number_list
    pass

def merge(temp_list, number_list, left, center, right):
    idx_l = left
    idx_r = center + 1
    idx_ct = 0
    while idx_r <= right:
        if number_list[idx_r] >= number_list[idx_l]:
            temp_list[idx_ct] = number_list[idx_l]
            idx_l += 1
            idx_ct += 1
            pass
        else:
            temp_list[idx_ct] = number_list[idx_r]
            idx_r += 1
            idx_ct += 1
        if idx_l > center:
            while idx_r <= right:
                temp_list[idx_ct] = number_list[idx_r]
                idx_r += 1
                idx_ct += 1

    while idx_l <= center:
        temp_list[idx_ct] = number_list[idx_l]
        idx_l += 1
        idx_ct += 1

    for i in range(idx_ct):
        number_list[left+i] = temp_list[i]

    for i in range(len(temp_list)):
        temp_list[i] = 0

    pass

def testMergesort():
    number_list = [364,637,341,406,747,995,234,971,571,219,993,407,416,366,315,301,601,650,418,355,460,505,360,965,516,648,727,667,465,849,455,181,486,149,588,233,144,174,557,67,746,550,474,162,268,142,463,221,882,576,604,739,288,569,256,936,275,401,497,82,935,983,583,523,697,478,147,795,380,973,958,115,773,870,259,655,446,863,735,784,3,671,433,630,425,930,64,266,235,187,284,665,874,80,45,848,38,811,267,575]
    temp_list = [0 for i in range(len(number_list))]

    print(mergeSort(temp_list, number_list, 0, len(number_list)-1))

testMergesort()

 輸出爲:[3, 38, 45, 64, 67, 80, 82, 115, 142, 144, 147, 149, 162, 174, 181, 187, 219, 221, 233, 234, 235, 256, 259, 266, 267, 268, 275, 284, 288, 301, 315, 341, 355, 360, 364, 366, 380, 401, 406, 407, 416, 418, 425, 433, 446, 455, 460, 463, 465, 474, 478, 486, 497, 505, 516, 523, 550, 557, 569, 571, 575, 576, 583, 588, 601, 604, 630, 637, 648, 650, 655, 665, 667, 671, 697, 727, 735, 739, 746, 747, 773, 784, 795, 811, 848, 849, 863, 870, 874, 882, 930, 935, 936, 958, 965, 971, 973, 983, 993, 995]

* merge函數還可以做重構 


逆序對應用

逆序對指的是在一串數字中前大後小的數字對。歸併的交換不重複,交換次數就可以用來統計逆序對的數量。

與排序的差別在於多了計數

 寫的時候一定要注意count的計數的位置,以及left和right的限制

def InversePairs(data):
    # write code here
    temp = [0 for i in range(len(data))]
    count = mergeCount(data, temp, 0, len(data) - 1)
    print(temp)
    return count

def mergeCount(data, temp, left, right):
    count = 0
    if left == right:
        return 0
    center = (left + right) // 2
    count += mergeCount(data, temp, left, center)
    count += mergeCount(data, temp, center + 1, right)

    idx_l = left
    idx_r = center + 1
    idx_ct = 0
    while idx_r <= right and idx_l <= center:
        if data[idx_r] >= data[idx_l]:
            temp[idx_ct] = data[idx_l]
            idx_ct += 1
            idx_l += 1
            pass
        else:
            count += center + 1 - idx_l
            temp[idx_ct] = data[idx_r]
            idx_ct += 1
            idx_r += 1
            pass
        pass
    while idx_r <= right:
        temp[idx_ct] = data[idx_r]
        idx_ct += 1
        idx_r += 1
        pass
    while idx_l <= center:
        temp[idx_ct] = data[idx_l]
        idx_ct += 1
        # count += center + 1 - idx_l
        idx_l += 1
        pass

    for i in range(idx_ct):
        data[left + i] = temp[i]
        pass

    return count

def testInversePairs():
    data = [364,637,341,406,747,995,234,971,571,219,993,407,416,366,315,301,601,650,418,355,460,505,360,965,516,648,727,667,465,849,455,181,486,149,588,233,144,174,557,67,746,550,474,162,268,142,463,221,882,576,604,739,288,569,256,936,275,401,497,82,935,983,583,523,697,478,147,795,380,973,958,115,773,870,259,655,446,863,735,784,3,671,433,630,425,930,64,266,235,187,284,665,874,80,45,848,38,811,267,575]
    print(InversePairs(data))

輸出爲:正常排序如上

逆序數爲:2519

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章