Insertion Sort List

https://leetcode.com/problems/insertion-sort-list/

Sort a linked list using insertion sort.

解题思路:

先回忆一下插入排序。对于num[i],将他插入到前面已经排好序的0...i-1的合适的位置。i从0-n遍历。

这题对于链表操作的难度在于取得当前节点和插入处的前趋节点,因为链表只有next。所以只能取travserse和insert的前一个节点往后遍历。这里还用了一个dummy,接在head前面,因为head可能随时发生变化。最终只要返回dumm.next即可。

这里最容易错的地方就是最后注释,如果traverseNode.next已经被搬到前面去了,其实traverseNode就不要再往后了,因为此时traverseNode.next已经是之前的下一个节点了。

/**

 * Definition for singly-linked list.

 * public class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode(int x) {

 *         val = x;

 *         next = null;

 *     }

 * }

 */

public class Solution {

    public ListNode insertionSortList(ListNode head) {

        if(head == null || head.next == null){

            return head;

        }

        

        ListNode dummy = new ListNode(0);

        dummy.next = head;

        //traverseNode.next是真正的当前遍历节点,插入在insertNode后面

        ListNode traverseNode = head;

        

        while(traverseNode != null && traverseNode.next != null){

            ListNode insertNode = dummy;

            boolean isSwap = false;

            while(insertNode != traverseNode.next){

                if(insertNode.next.val > traverseNode.next.val){

                    isSwap = true;

                    ListNode tempNode = traverseNode.next;

                    traverseNode.next = tempNode.next;

                    tempNode.next = insertNode.next;

                    insertNode.next = tempNode;

                    break;

                }

                insertNode = insertNode.next;

            }

            //如果traverseNode.next插入到前面去了,traverseNode就不用往后了

            //比如3-2-1,2到前面去了,原来3.next=2,现在3.next=1,其实已经相当于往后一个了

            if(!isSwap){

                traverseNode = traverseNode.next;

            }

        }

        return dummy.next;

    }

}

后来在网上看到另一种方法,http://blog.csdn.net/linhuanmars/article/details/21144553,代码反而更简单。

上面我的方法是类似于一个in-place的方法,它不另外构造一个list的结构,而是在原来的list里调换各个node的顺序。下面的方法是,索性从dummy开始,重新组成一个list,所以这里dummy没有接在head后面。但实际上,由于链表的特点,即使不是in-place的,也不需要占新的内存。

代码比上面我的方法清晰很多。

/**

 * Definition for singly-linked list.

 * public class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode(int x) {

 *         val = x;

 *         next = null;

 *     }

 * }

 */

public class Solution {

    public ListNode insertionSortList(ListNode head) {

        if(head == null || head.next == null){

            return head;

        }

        

        ListNode dummy = new ListNode(0);

        // dummy.next = head;

        

        ListNode cur = head;

        while(cur != null){

            ListNode pre = dummy;

            while(pre.next != null && pre.next.val <= cur.val){

                pre = pre.next;

            }

            ListNode next = cur.next;

            cur.next = pre.next;

            pre.next = cur;

            cur = next;

        }

        return dummy.next;

    }

}

 

你可能感兴趣的:(insert)