# 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:
if not head: return
# 初始化:伪头节点h指向head(伪头节点用于遍历链表),链表长度length为0,归并排序的子链表长度intv为最小长度1
h, length, intv = head, 0, 1
# 初始化:指向头节点head的辅助节点res
res = ListNode(0)
res.next = head
# 遍历一遍链表,得到链表长度
while h: h, length = h.next, length + 1
# 当子链表的长度小于原始链表长度时,对链表进行归并排序
while intv < length:
# 归并排序每轮合并过程开始时,重新初始化:用于链接两个子链表的辅助节点pre与伪头节点h
pre, h = res, res.next
# 当链表本轮还未局部排序完时,进行循环
while h:
## 断链过程 Cut
# 移动链表来确定第一个子链表中元素个数情况
h1, i = h, intv
while i > 0 and h: h, i = h.next, i - 1
# 若第一个子链表的元素个数不足本轮的intv,则不存在第二个子链表,直接终止循环
if i > 0: break
# 移动链表来确定第二个子链表中元素个数情况(此时从上一步剩余的h继续判断,表示将两个子链表分开Cut)
h2, i = h, intv
while i > 0 and h: h, i = h.next, i - 1
## 合并过程 Merge
# 合并时需要确定两个子链表的元素数量(其中第二个子链表中元素数量可能不足本轮的intv,因此需要减去上一步中剩余的i个元素)
n1, n2 = intv, intv - i
# 当两个子链表中均剩余元素时,可以进行大小比较
while n1 > 0 and n2 > 0:
# 根据元素值大小来排序,选择正确的值来链接链表,并移动链表
if h1.val < h2.val: pre.next, h1, n1 = h1, h1.next, n1 - 1
else: pre.next, h2, n2 = h2, h2.next, n2 - 1
pre = pre.next # 每链接完一个元素,pre后移一位
# 处理可能剩余的链表元素,并让pre移动到已经排序完成的元素之后
pre.next = h1 if n1 > 0 else h2
while n1 > 0 or n2 > 0: pre, n1, n2 = pre.next, n1 - 1, n2 - 1
# 将剩余未排序的元素链接到pre之后
pre.next = h
# 本轮归并完成,下一轮的intv翻倍
intv *= 2
return res.next # 最后返回链表头