1.题目
2.思路
学408也有要求自顶向下的递归版归并排序,只不过这里是链表的形式,而非数组,但思路都是一毛一样,将链表分成两段,再递归把每段继续分成2段,最后“到底后”就往上通过merge
合并成有序列。
sortlist函数:将含有n个元素的待排序表分成各含有n/2个元素的子表,采用二路归并排序对2个子表递归进行排序
merge函数:合并2个已排序的子表得到排序结果
在python中可以使用if-else三元表达式进行【简写】,所以在merge的最后将比较完多出来的A或B链继续接入新链尾巴,就可简写为pre.next = headA if headA else headB
。
if X:
A = Y
else:
A = Z
#上面的写法等价于下面的写法
A = Y if X else
3.递归版代码
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
#将含有n个元素的待排序表分成各含有n/2个元素的子表,
#采用二路归并排序对2个子表递归进行排序
def sortList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
slow, fast = head, head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
head2 = slow.next
slow.next = None # 断开链表
return self.merge(self.sortList(head), self.sortList(head2))
#合并2个已排序的子表得到排序结果
def merge(self, headA, headB):
dummyhead = pre = ListNode(0)
while headA and headB:
if headA.val <= headB.val:
pre.next = headA
headA = headA.next
else:
pre.next = headB
headB = headB.next
pre = pre.next
pre.next = headA if headA else headB
return dummyhead.next
最后mark一个用python实现数组的归并排序的版本:
def mergesort(arr):
if len(arr) <2:
return arr
middle = len(arr) // 2
left,right = arr[:middle],arr[middle:]
return merge(mergesort(left),mergesort(right))
def merge(left,right):
result = []
while left and right:
if left[0] < right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
while left:
result.append(left.pop(0))
while right:
result.append(right.pop(0))
return