'''
148. 排序链表
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
排序算法中的时间复杂度涉及到log n,都需要用到二分的策略,
链表常用的排序算法是归并排序,归并排序算法的时间复杂度是 nlogn
归并排序是 divide and conquer的策略,
divide 递归深度 log n conquer的复杂度n
首先将原始未被排序的链表划分成前后两个子链表(子链表也没有被排序好)
划分过程需要使用到慢指针和快指针,分别标记为slow和fast
再将两个链表分别递归使用排序算法,返回的是两个已经排序好的子链表
最后将两个排序好的子链表进行合并 merge 这一步骤所需要的时间复杂度是 O(n)
'''
# Definition for singly-linked list.
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def sortList(self, head: ListNode) -> ListNode:
if head is None or head.next is None:# 递归基,对应于平凡的情况
return head
else:
# 如果链表的长度大于1,就使用slow指针和fast指针分别指向当前输入的链表的
# 中间节点和末尾节点
# 设置链表头部的哨兵节点
head_helper=ListNode(-float('inf'))
head_helper.next=head
slow=head_helper
fast=head_helper
while(1):
i=2
while(fast is not None and i>0):
fast=fast.next
i-=1
if fast==None:
break
slow = slow.next
# 此时slow指针指向的是无序链表中间节点
# fast指向的是链表尾部的None
left_start=head_helper.next
right_start=slow.next
slow.next=None
left=self.sortList(left_start)# 返回对左部分链表进行排序之后的结果
right=self.sortList(right_start)# 返回对右部分链表进行排序之后的结果
# 将左右两个排序好的链表进行merge归并
# left 和 right两个指针分别指向排序好的链表的头部节点
output=ListNode(-float('inf'))
temp=output
while left and right:
if left.val<=right.val:
temp.next=left
left=left.next
temp=temp.next
else:
temp.next=right
right=right.next
temp=temp.next
if left is not None:
temp.next=left
elif right is not None:
temp.next=right
return output.next
if __name__=="__main__":
start=ListNode(-float('inf'))
temp=start
for elem in [-1,5,3,4,0]:
new_node=ListNode(elem)
temp.next=new_node
temp=temp.next
output=Solution().sortList(start.next)
while(output):
print(output.val)
output=output.next