python實現歸併排序

       堆排序和歸併排序以及快速排序是比較經典的排序方法。堆排序的時間複雜度是nlogn,歸併排序的時間複雜度可以達到O(n),快速排序的時間複雜度是nlogn。可見歸併排序的排序速度比較快,但是比較耗費內存,畢竟是通過遞歸的方式來切分待排序序列。

      堆排序可以參考我的上一篇博客。歸併排序從字面意思來看,有兩個過程:“歸”和“並”。“歸”是遞歸的意思,“並”當然是合併的意思。

     “歸”。遞歸是歸併排序的核心思想。其基本思想是對於一個無序的序列我們總是可以將它一分爲二。直到切分出來的序列有序。按照這個分法,我們總可以通過有限步的切分,將待排序序列切分成若干個有序的子序列。然後通過遞歸的逆過程,將切分出來的有序子序列進行合併。下面給出一個例子:

        對序列 sequence = [9, 5 , 7, 2]進行歸併排序。序列切分方法:left = len(sequence ) // 2

1、left_sequence = [9, 5]                right_sequence = [7, 2]

    顯然left_sequence 是沒有順序的,需要按照上面的方法繼續進行切分。

2、left_sequence_1 = [9]                right_sequence_1 = [5]

      顯然 left_sequence_1 和 right_sequence_1 都是有順序的序列。我們不再對其進行切分

3、left_sequence_2 = [7]                right_sequence_2 = [2]

      顯然 left_sequence_2 和 right_sequence_2 都是有順序的序列。我們不再對其進行切分

通過這3步,遞歸過程就完成了。

    “並”。遞歸的逆過程。通過上面的例子,我們可以很清楚的看到總共切分除了4個子序列。將 left_sequence_2 和         right_sequence_2進行合併。這裏需要提一下,合併的方法有很多。最有效的方法可能就是下面的這種形式:

            while  left_index   <  len(left_sequence_2):

                       right_sequence_2.append[right_sequence_2[0]]  # 從上個序列取出的元素必須要放到第二個序列中。

                              while right_index < len(right_sequence_2) - 1:  # 減1,sequence_2最後一個元素不需要比較

                                      if  right_sequence_2[right_index] < left_sequence_2[left_index]:

                                            right_index += 1

                                        else:

                                                right_sequence_2中的元素從right_index索引對應的元素開始後移

                                        right_sequence_2[right_index] = left_sequence_2[left_index]

        第一次合併產生的序列:[5, 9]

        第二次合併產生的序列:[2, 7]

        第三次合併產生的序列:[2,5,,7,9]

        下面給出使用python編制的歸併排序的代碼:

import sys


class Solution:
    def __init__(self):
        pass

    def getdata(self):
        read_line = sys.stdin.readline().split()
        read_line = list(map(lambda x: int(x), read_line))
        return read_line

    def gbpx(self, data):
        assert hasattr(data, '__len__')
        assert len(data) > 0
        len_data = len(data)
        if len_data == 1:
            return data
        for cur_data_index in range(1, len_data, 1):
            if data[cur_data_index] < data[cur_data_index - 1]:
                middle = len_data // 2
                left = data[:middle]  # 9 5
                right = data[middle:len_data]  # 2 7
                left_ordeted = self.gbpx(left)
                right_ordered = self.gbpx(right)
                print((left_ordeted, right_ordered))
                index_left = 0
                index_right = 0
                while index_left < len(left_ordeted):
                    right_ordered.append(right_ordered[0])
                    while index_right < len(right_ordered) - 1:
                        if right_ordered[index_right] < left_ordeted[index_left]:
                            index_right += 1
                        else:
                            for mov_index in range(index_right, len(right_ordered), 1):
                                right_ordered[mov_index], right_ordered[-1] = right_ordered[-1],\
                                                                                  right_ordered[mov_index]
                            right_ordered[index_right] = left_ordeted[index_left]
                            break
                    right_ordered[index_right] = left_ordeted[index_left]
                    index_left += 1
                    print('tmp:', right_ordered)
                return right_ordered
        return data


if __name__ == '__main__':
    so = Solution()
    print(so.gbpx(so.getdata()))
結果:
7 4 1 5 8 9 6 2 1 4 7 5 1
([4], [1])
tmp: [1, 4]
([7], [1, 4])
tmp: [1, 4, 7]
([1, 4, 7], [5, 8, 9])
tmp: [1, 5, 8, 9]
tmp: [1, 4, 5, 8, 9]
tmp: [1, 4, 5, 7, 8, 9]
([2], [1])
tmp: [1, 2]
([6], [1, 2])
tmp: [1, 2, 6]
([5], [1])
tmp: [1, 5]
([4, 7], [1, 5])
tmp: [1, 4, 5]
tmp: [1, 4, 5, 7]
([1, 2, 6], [1, 4, 5, 7])
tmp: [1, 1, 4, 5, 7]
tmp: [1, 1, 2, 4, 5, 7]
tmp: [1, 1, 2, 4, 5, 6, 7]
([1, 4, 5, 7, 8, 9], [1, 1, 2, 4, 5, 6, 7])
tmp: [1, 1, 1, 2, 4, 5, 6, 7]
tmp: [1, 1, 1, 2, 4, 4, 5, 6, 7]
tmp: [1, 1, 1, 2, 4, 4, 5, 5, 6, 7]
tmp: [1, 1, 1, 2, 4, 4, 5, 5, 6, 7, 7]
tmp: [1, 1, 1, 2, 4, 4, 5, 5, 6, 7, 7, 8]
tmp: [1, 1, 1, 2, 4, 4, 5, 5, 6, 7, 7, 8, 9]
[1, 1, 1, 2, 4, 4, 5, 5, 6, 7, 7, 8, 9]


Process finished with exit code 0







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