对链表进行插入排序
对链表进行插入排序。
输入: 4->2->1->3输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0输出: -1->0->3->4->5
public ListNode insertionSortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode cur = head.next;//当前指针
ListNode pre = head;//前一个指针,用于链接后面的元素
while (cur != null) {
if(cur.val>=pre.val){//比前一个大,说明有序了
cur=cur.next;
pre=pre.next;
continue;
}
ListNode p=dummy;
ListNode next=cur.next;//记录next
while (cur.val>p.next.val){//从头开始找
p=p.next;
}
pre.next=next;//链向遍历过程中的下一个
cur.next=p.next;//插入
p.next=cur;
cur=next;
}
return dummy.next;
}
从头开始比较
public ListNode insertionSortList(ListNode head) {
ListNode dummy = new ListNode(0);
ListNode cur = head;
while (cur != null) {
ListNode next = cur.next;
ListNode p = dummy;
while (p.next != null && p.next.val < cur.val) {
p = p.next;
}
if (p.next != null) {//插入到已经有序链表的中间
cur.next = p.next;
} else {//插入到已经有序的链表的末尾
cur.next = null;
}
p.next = cur;
cur = next;
}
return dummy.next;
}
一点优化:
public ListNode insertionSortList(ListNode head) {
ListNode dummy = new ListNode(0);
ListNode cur = head;
ListNode pre = dummy;//记录已经有序的链尾,即最大的元素
while (cur != null) {
ListNode next = cur.next;
if (cur.val >= pre.val) {//比最大的还大,直接链在链尾
pre.next = cur;
cur.next = null;
pre = cur;
cur = next;
continue;
}
ListNode p = dummy;
while (p.next != null && p.next.val < cur.val) {
p = p.next;
}
if (p.next != null) {
cur.next = p.next;
} else {
cur.next = null;
pre = cur;
}
p.next = cur;
cur = next;
}
return dummy.next;
}
排序链表
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序
归并排序:
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode mid = middleNode(head);
ListNode rightHead = mid.next;
mid.next = null;
ListNode left=sortList(head);
ListNode right=sortList(rightHead);
return merge(left,right);
}
//返回链表终点
public ListNode middleNode(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode slow = head;
ListNode fast = head.next.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public ListNode merge(ListNode head1, ListNode head2) {
ListNode p1 = head1;
ListNode p2 = head2;
ListNode newHead = new ListNode(0);
ListNode p = newHead;
while (p1 != null && p2 != null) {
if (p1.val <= p2.val) {
p.next = p1;
p1 = p1.next;
} else {
p.next = p2;
p2 = p2.next;
}
p = p.next;
}
if(p1!=null){
p.next=p1;
}
if(p2!=null){
p.next=p2;
}
return newHead.next;
}