148. Sort List & 147. Insertion Sort List

本文介绍如何使用归并排序和插入排序对链表进行排序。归并排序采用递归方式将链表分成两半,然后合并两个有序的部分。插入排序则是通过不断插入元素来构建有序链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Sort a linked list in O(n log n) time using constant space complexity.

链表排序,O(n log n) time就考虑快排,归并排序,堆排,三者的空间复杂度分别为O(1), O(N),O(N),其实在链表里面的归并排序空间只要O(1)。

归并排序就是先切分为一半一半,一直切到只有一个节点,在一步步merge,用递归做:

public class Solution {
    public ListNode sortList(ListNode head) {
        if(head == null || head.next == null)	return head;
        
        ListNode mid = getMid(head);
        ListNode part1 = sortList(head);
        ListNode part2 = sortList(mid);
        ListNode rst = merge(part1, part2);
        
        return rst;
    }
    
    private ListNode merge(ListNode p1, ListNode p2) {
    	ListNode dummy = new ListNode(0), tmp = dummy;
    	
    	while(p1 != null && p2 != null) {
    		if(p1.val > p2.val) {
    			tmp.next = p2;
    			p2 = p2.next;
    		} else {
    			tmp.next = p1;
    			p1 = p1.next;
    		}
    		tmp = tmp.next;
    	}
    	
    	if(p1 != null)	tmp.next = p1;
    	
    	if(p2 != null)	tmp.next = p2;
    	
		return dummy.next;
	}

	public ListNode getMid(ListNode head) {
    	ListNode fast = head, slow = head;
    	while(fast.next != null && fast.next.next != null) {
    		fast = fast.next.next;
    		slow = slow.next;
    	}
    	
    	ListNode tmp = slow.next;
    	slow.next = null;
    	return tmp;
    }
}

 

用快排也不是不可以,不过paritition要换一种方式,详见

http://www.cnblogs.com/TenosDoIt/p/3666585.html

http://www.cnblogs.com/TenosDoIt/p/3665038.html

 

 

Sort a linked list using insertion sort.


A graphical example of insertion sort. The partial sorted list (black) initially contains only the first element in the list.
With each iteration one element (red) is removed from the input data and inserted in-place into the sorted list
 

Algorithm of Insertion Sort:

  1. Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list.
  2. At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there.
  3. It repeats until no input elements remain.

 

插入排序是从后往前找合适的插入位置,如果要在链表上从后往前的话,只能让指针反向指

也就是大的数在链表的前面,指针指向左边

public ListNode insertionSortList(ListNode head) {
	if( head == null ){
		return head;
	}
	
	ListNode helper = new ListNode(0); //new starter of the sorted list
	ListNode cur = head; //the node will be inserted
	ListNode pre = helper; //insert node between pre and pre.next
	ListNode next = null; //the next node will be inserted
	//not the end of input list
	while( cur != null ){
		next = cur.next;
		//find the right place to insert
		while( pre.next != null && pre.next.val < cur.val ){
			pre = pre.next;
		}
		//insert between pre and pre.next
		cur.next = pre.next;
		pre.next = cur;
		pre = helper;
		cur = next;
	}
	
	return helper.next;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值