147. 对链表进行插入排序(中等)

思路:

数组的插入排序是从最后一个从后往前遍历找到合适的位置插入,而链表不能往前遍历,则需要一个带头节点的指针,从前往后遍历找到合适的位置插入

代码:

class Solution {
    public ListNode insertionSortList(ListNode head) {
		//是return head而不是0
		if(head==null) return head;
		//只是一个空链表,不带头节点
		ListNode hair=new ListNode(0);
		hair.next=head;
		
		ListNode lastSorted=head,curr=head.next;
		
		//此处是curr而不是curr.next
		while(curr!=null){
			//是"<="
			if(lastSorted.val<=curr.val){
				lastSorted=lastSorted.next;
				curr=curr.next;
			}else{
				//用到的时候再创建,不要一开始就创建。这样可以减少内存开销
				ListNode prev=hair;
				//是"<="
				while(prev.next.val<=curr.val){
					prev=prev.next;
				}
				lastSorted.next=curr.next;
				curr.next=prev.next;
				prev.next=curr;
				
				//重置,把curr继续放在lastSorted后面,继续遍历
				curr=lastSorted.next;
			}
		}
		return hair.next;
	}
}

分解:

1)需要一个带头节点的指针hair,一个lastsortedcurr。lastsorted相当于已经排好序的最后一个元素,属于内循环。curr是没有排好序的第一个元素,属于外循环。一个prev,用于从前往后内循环,在内循环最后一个元素比外循环第一个元素大的时候才创建,这样可以减少内存的消耗,提高性能

2)若内循环最后一个元素比外循环第一个元素小,则两个指针都向后移一个

    if(lastSorted.val<=curr.val){
	lastSorted=lastSorted.next;
	curr=curr.next;
    }

3)调换顺序的代码

    ListNode prev=hair;
	//是"<="
	while(prev.next.val<=curr.val){
	    prev=prev.next;
	}
	lastSorted.next=curr.next;
	curr.next=prev.next;
	prev.next=curr;
				
	//重置,把curr继续放在lastSorted后面,继续遍历
	curr=lastSorted.next;

猜你喜欢

转载自blog.csdn.net/di_ko/article/details/115112041