Python实现归并排序

归并排序执行过程:
          1、执行归并排序函数时,把全部的数字一分为二,继续递归调用函数自身,左一半右一半的划分开,直到每一份里只有一个元素为止,停止划分。
         2、把划分开的元素按照大小顺序排列,先 1 1,合并为个数为 2 的数组,再把 2 2 按顺序大小要求合并成个数为 4 的数组,依次进行把所有元素按大小排序
            两两合并时两序列均已是有序序列

如:
    4 1 3 10 7 3 5 0
    
    4 1 3 10 7 3 5 0

    4 1 3 10 7 3 5 0

    4 1 3 10 7 3 5 0 //每一组个数为 1 结束



合并:  1 4 3 10 3 7 0 5

      1 3 4 10 0 3 5 7

最后结果:   0 1 3 3 4 5 7 10



目标序列:
l = [1000, 5, 6, 7, 3, 30, 25, 12, 9, 13, 10, 8]
def mergesort(left, mid, right):
    l_1, l_2 = l[left:mid], l[mid:right]
    print("归并前:", l_1, l_2)
    len1 = len(l_1)
    len2 = len(l_2)
    a, b, l3 = 0, 0, []
    while a < len1 and b < len2:
        if l_1[a] <= l_2[b]:
            l3.append(l_1[a])
            a += 1
        else:
            l3.append(l_2[b])
            b += 1
    while a < len1:
        l3.append(l_1[a])
        a += 1
    while b < len2:
        l3.append(l_2[b])
        b += 1
    l[left:right] = l3[:]
    print("后:", l)


def sor(left, right):
    if left < right:
        mid = int((left + right) / 2)
        sor(left, mid)
        sor(mid+1, right)
        mergesort(left, mid+1, right+1)


sor(0, 11)
print("\n完毕:", l)

 

执行过程

归并前: [1000] [5]
后: [5, 1000, 6, 7, 3, 30, 25, 12, 9, 13, 10, 8]
归并前: [5, 1000] [6]
后: [5, 6, 1000, 7, 3, 30, 25, 12, 9, 13, 10, 8]
归并前: [7] [3]
后: [5, 6, 1000, 3, 7, 30, 25, 12, 9, 13, 10, 8]
归并前: [3, 7] [30]
后: [5, 6, 1000, 3, 7, 30, 25, 12, 9, 13, 10, 8]
归并前: [5, 6, 1000] [3, 7, 30]
后: [3, 5, 6, 7, 30, 1000, 25, 12, 9, 13, 10, 8]
归并前: [25] [12]
后: [3, 5, 6, 7, 30, 1000, 12, 25, 9, 13, 10, 8]
归并前: [12, 25] [9]
后: [3, 5, 6, 7, 30, 1000, 9, 12, 25, 13, 10, 8]
归并前: [13] [10]
后: [3, 5, 6, 7, 30, 1000, 9, 12, 25, 10, 13, 8]
归并前: [10, 13] [8]
后: [3, 5, 6, 7, 30, 1000, 9, 12, 25, 8, 10, 13]
归并前: [9, 12, 25] [8, 10, 13]
后: [3, 5, 6, 7, 30, 1000, 8, 9, 10, 12, 13, 25]
归并前: [3, 5, 6, 7, 30, 1000] [8, 9, 10, 12, 13, 25]
后: [3, 5, 6, 7, 8, 9, 10, 12, 13, 25, 30, 1000]

完毕: [3, 5, 6, 7, 8, 9, 10, 12, 13, 25, 30, 1000]

Process finished with exit code 0

 

 

剑指 Offer II 077. 链表排序

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        """
        归并排序是稳定排序,时间复杂度 nlog(n), 空间复杂度 O(n):合并过程中需要一个额外的数组来存储合并后的有序序列
        """

        # 1. 取出数字排序,重构链表 Time: nlog(n), Space: o(n)
        # 2. 归并排序

        nums = []
        while head:
            nums.append(head.val)
            head = head.next
        # print(nums)

        n = len(nums)

        def mergesort(l, r):
            """
            [l, r] 递归划分为两个区间,直到剩一个元素为止
            """
            if l < r:
                mid = (l+r) // 2
                mergesort(l, mid)
                mergesort(mid+1, r)
                merge(nums, l, mid, mid+1, r)  # 合并区间

        def merge(nums, l1, r1, l2, r2):
            """合并两个区间
            [l1, r1] & [l2, r2]
            """
            temp = []  # 存以上两区间排序之后的结果
            i, j = l1, l2
            while i <= r1 and j <= r2:
                if nums[i] <= nums[j]:
                    temp.append(nums[i])
                    i += 1
                else:
                    temp.append(nums[j])
                    j += 1
            # 加入区间一的剩余,区间二的元素值小于区间一导致的
            while i <= r1:
                temp.append(nums[i])
                i += 1
            # 加入区间二的剩余,区间一的元素值小于区间二导致的
            while j <= r2:
                temp.append(nums[j])
                j += 1
            nums[l1:r2+1] = temp

        mergesort(0, n-1)
        # print(nums)

        thead = ListNode()
        t = thead
        for x in nums:
            a = ListNode(x)
            t.next = a
            t = t.next
        
        return thead.next

 

posted @ 2018-04-06 16:15  961897  阅读(275)  评论(0编辑  收藏  举报