前置函数
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def build_list(listInput):
node = None
for i in range(len(listInput)-1, -1, -1):
node = ListNode(val=listInput[i], next=node)
return node
def print_list(head):
node = []
cur = head
while cur:
node.append(cur.val)
cur = cur.next
print(node)
# 测试代码
nodes = [4, 2, 1, 3, 1, 6]
head = build_list(nodes)
ob = Solution()
res = ob.sortList(head )
冒泡排序
class Solution:
def sortList(self, head):
# 如何输入链表为空,或者只有一个元素就直接返回
if not head or not head.next: return head
# 统计链表里面元素的个数n
cur = head
n = 0
while cur:
n += 1
cur = cur.next
# 构造一个虚拟头结点
headNew = ListNode(val=0, next=head)
# 冒泡排序法实现链表的排序
for i in range(1, n):
print_list(headNew.next)
pre = headNew
cur = headNew.next
nex = headNew.next.next
for j in range(n-i):
nex_nex = nex.next
if cur.val > nex.val:
# 如果当前元素的值大于它的下一个元素的值
# 说面要进行交换
# 分三步:
# 1、下个元素指向当前元素
# 2、当前元素指向下下元素
# 3、前元素指向下个元素
nex.next = cur
cur.next = nex_nex
pre.next = nex
# 更新前元素为下个元素
# 当前元素不能再更新,因为前面已经更新为中间元素了
pre = nex
else:
# 正常更新前元素和当前元素
pre = cur
cur = nex
# 更新下个元素为下下元素
nex = nex_nex
return headNew
打印结果
[4, 2, 1, 3, 1, 6]
[2, 1, 3, 1, 4, 6]
[1, 2, 1, 3, 4, 6]
[1, 1, 2, 3, 4, 6]
[1, 1, 2, 3, 4, 6]
插入排序
class Solution:
def sortList(self, head):
if not head or not head.next: return head
newHead = ListNode(val=0, next=head)
# 插入排序法实现链表的排序
# 指向链表的虚拟头结点
# 每次从头开始比较每个元素与当前元素的大小
# 用来确定当前元素该插入链表中的哪个位置
pre = newHead
# 为了指向已经排好序的链表的最后一个元素
lastSorted = newHead.next
# 当前元素,即未排序中的第一个元素,
# 也是lastSorted后面的一个元素
cur = newHead.next.next
while cur:
print_list(newHead.next)
if cur.val < lastSorted.val:
# 循环遍历,直到找到当前元素该插入的位置
while pre.next.val < cur.val:
pre = pre.next
### 核心交换部分
# 链表位置交换
lastSorted.next = cur.next
cur.next = pre.next
pre.next = cur
### 交换结束
# 更新cur和pre
cur = lastSorted.next
pre = newHead
else:
# 更新cur和lastSorted
cur = cur.next
lastSorted = lastSorted.next
return newHead.next
打印结果
[4, 2, 1, 3, 1, 6]
[2, 4, 1, 3, 1, 6]
[1, 2, 4, 3, 1, 6]
[1, 2, 3, 4, 1, 6]
[1, 1, 2, 3, 4, 6]
注意:由于插入没有像冒泡排序那样每次对比都进行位置的交换,而是找到插入位置后直接将当前元素放在插入位置,虽然时间复杂度仍是O(N^2),但交换的次数明显比冒泡排序少,所以比冒泡排序还是快不少