LintCode 链表插入排序

1.描述

用插入排序对链表排序

样例

Given 1->3->2->0->null, return 0->1->2->3->null

2.分析

插入排序是十分常见的排序方式之一,类似于数组的插入排序,此题是关于链表的插入排序。

原题给定一个以head为头节点的链表,下面再新建一个有序的dummy链表,通过把head链表

中的节点分别插入到dummy链表中完成对head链表的排序。思路为在有序链表中依次向下查找

和原链表中的值比较,当有序链表的值比原链表的值大时,把该值插入到有序链表中。举个例子如

有序链表中有1、3,原链表中为2。1和2先做比较,1小于2,继续向下查找,3比2大,此时把原链表

中的2插入到1、3之间最终得到有序链表1、2、3。

在有序链表中依次向下查找通过node=node->next完成指针向后移,之后的具体分析我在重要代码

后面都加了注释。下面的dummy链表为新建的有序链表,head链表为原链表。为了能够返回有序链表,

dummy链表的头节点dummy我没有动,而另外定义了一个node指针,而head链表中不需要返回原链表,

故直接用head作为指针依次往下移动(若还想要返回head指针需把头节点保存下来),node指针为

dummy链表里不断向下移动的指针,head指针为head链表里不断向下移动的指针。

3.代码

/**
 * Definition of ListNode
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *         this->val = val;
 *         this->next = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     * @param head: The first node of linked list.
     * @return: The head of linked list.
     */
    ListNode *insertionSortList(ListNode *head) {
        // write your code here
    ListNode *dummy=new ListNode(0);
        while(head!=NULL)
     {
         ListNode *node=dummy;
         while(node->next!=NULL && node->next->valval)
         {
             node=node->next;/*node指针后移一位,直到找到一个比head链表里的数大的,
                            把这个数添加到dummy链表里*/
         }
         ListNode *temp=head->next;/*以head为原链表里的指针依次向下查找,跳出while循环时
                                     查到的这个head比node.next大*/
         head->next=node->next;//把head插入node.next前
         node->next=head;//把head插入到node后,完成head插入到node和node.next之间
         head=temp;//原head.next成为新的head继续循环查找
        }
        return dummy->next;
    }
};

4.总结

在对链表做操作时有一个很大的特点,就是head->next的变化一定要最后做。因为给定head节点时

head->next随机确定下来,head->next就是下一个节点,然而如果过早改变这个节点就找不到了,如

红字部分代码也是先把head->next存到temp中,之后做过一系列操作后head->next的地址已经改变,

但temp把原来head的下一个节点保留了下来。

同时,单链表是有next支撑的,当插入新元素时,如把2插入到1和3之中,原有的关系是1->next=3;

插入后变为1->next=2,2->next=3,是斩断之前两个节点之间关系的基础上建立新的两个关系。



你可能感兴趣的:(链表,单链表,插入排序)