Skip to content
本页目录

0148-排序链表

https://leetcode.cn/problems/sort-list

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

示例 1:

输入:head = [4,2,1,3]
输出:[1,2,3,4]

示例 2:

输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]

示例 3:

输入:head = []
输出:[]

提示:

链表中节点的数目在范围 [0, 5 * 10^4] 内
-10^5 <= Node.val <= 10^5

进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

思路:暴力冒泡排序(超时)

常规冒泡排序,主要是要注意交换节点

参考代码

csharp
public class Solution {
    public ListNode SortList(ListNode head) {
    	ListNode dummyHead = new ListNode();
    	dummyHead.next = head;
    	//冒泡排序
    	ListNode p1 = head;
    	while(p1 != null){
    		ListNode p2 = p1.next;
    		while(p2 != null){
    			if(p1.val > p2.val){
    				int temp = p1.val;
    				p1.val = p2.val;
    				p2.val = temp;
    			}
    			p2 = p2.next;
    		}
    		p1 = p1.next;
    	}
    	return dummyHead.next;
    }
}

思路2:归并排序

最适合链表的排序算法是归并排序

参考代码

  1. 将链表从中间分开,查找中点的方式是使用快慢指针,快的走两格,慢的走一格,快的走到底的时候慢的正好在中间
  2. 拆接出两个列表,递归调用排序(当最后只有一个节点的时候,会直接返回一个节点)
  3. 排序完成后,将两个链表合并
  4. 排序的时候,递归完成
csharp
public class Solution {

    public ListNode SortList(ListNode head) {
    	if(head == null || head.next == null){
    		return head;
    	}
    	//找寻中点
    	ListNode fast = head;
    	ListNode slow = head;

    	while(fast != null){
    		fast = fast.next;
    		slow = slow.next;
    		if(fast != null){
    			fast = fast.next;
    		}
    	}
    	//slow 为中点
    	//构建第二个 List
    	ListNode list2 = slow;

    	//构建第一个 List
    	ListNode list1 = head;
    	ListNode cur = head;
    	while(cur != null){
    		if(cur.next == list2){
    			cur.next = null;
    			break;
    		}
    		cur = cur.next;
    	}

    	//递归调用
    	list1 = SortList(list1);
    	list2 = SortList(list2);

    	//Merge
    	ListNode result = MergeList(list1,list2);
    	return result;
    }

    //合并两个有序列表
    private ListNode MergeList(ListNode head1, ListNode head2){
    	ListNode dummyHead = new ListNode();
    	ListNode cur = dummyHead;

    	while(head1 != null && head2 != null){
    		if(head1.val < head2.val){
    			cur.next = head1;
    			head1 = head1.next;
    		}
    		else{
    			cur.next = head2;
    			head2 = head2.next;
    		}
    		cur = cur.next;
    	}
    	if(head1 != null){
    		cur.next = head1;
    	}
    	if(head2 != null){
    		cur.next = head2;
    	}

    	return dummyHead.next;
    }
}

Released under the MIT License.