1. 插入排序(链表)
来源:147题
使用插入排序的方法对链表进行排序,其时间复杂度是 O ( n 2 ) O(n^2) O(n2), n n n是链表的长度:
class Solution {
public ListNode insertionSortList(ListNode head) {
if (head == null) {
return head;
}
//创建哑节点 dummyHead
//引入哑节点是为了便于在 head 节点之前插入节点。
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
//维护 lastSorted 为链表的已排序部分的最后一个节点
//维护 curr 为待插入的元素
//
ListNode lastSorted = head, curr = head.next;
while (curr != null) {
if (lastSorted.val <= curr.val) {
lastSorted = lastSorted.next;
} else {
ListNode prev = dummyHead;
while (prev.next.val <= curr.val) {
prev = prev.next;
}
lastSorted.next = curr.next;
curr.next = prev.next;
prev.next = curr;
}
curr = lastSorted.next;
}
return dummyHead.next;
}
}
2. 归并排序(链表)
来源:147题
时间复杂度是 O ( n log n ) O(n \log n) O(nlogn) 的排序算法:归并排序、堆排序和快速排序(快速排序的最差时间复杂度是 O ( n 2 ) O(n^2) O(n2)):
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
return sort(head,null);
}
public ListNode sort(ListNode head, ListNode tail){
//递归的终止条件是链表的节点个数小于或等于 11
//即当链表为空或者链表只包含 11 个节点时,不需要对链表进行拆分和排序
if(head==null)return head;
if(head.next == tail){
head.next = null;
return head;
}
//寻找链表的中点可以使用快慢指针的做法:快指针每次移动 2 步,慢指针每次移动 1 步
//当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。
ListNode slow = head, fast = head;
while(fast!=tail){
slow = slow.next;
fast = fast.next;
if(fast!=tail) fast = fast.next;
}
ListNode mid = slow;
ListNode list1 = sort(head, mid);
ListNode list2 = sort(mid, tail);
ListNode merge = merge(list1, list2);
return merge;
}
public ListNode merge(ListNode head1, ListNode head2){
ListNode dummyNode = new ListNode(0);
ListNode tmp = dummyNode, tmp1 = head1, tmp2 = head2;
while(tmp1!=null && tmp2!=null){
if(tmp1.val<=tmp2.val){
tmp.next = tmp1;
tmp1 = tmp1.next;
}else{
tmp.next = tmp2;
tmp2 = tmp2.next;
}
tmp = tmp.next;
}
if(tmp1!=null){
tmp.next = tmp1;
}else if(tmp2!=null){
tmp.next = tmp2;
}
return dummyNode.next;
}
}