LeetCode147. 对链表进行插入排序

题目来源:

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

题目描述: 

对链表进行插入排序。


插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。

插入排序算法:

  1. 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
  2. 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
  3. 重复直到所有输入数据插入完为止。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

算法描述:

从第二个结点向链表末尾遍历,对每个遍历的结点进行插入排序。假设这时候遍历到第n个结点,也就是要对第n个结点进行排序时。拿出另外一个指针从头开始遍历,找到那个大于当前待排序结点的结点,将待排序结点插入到那个结点之前就可以了。这里需要注意的是,当待排序结点要插入的位置是头结点的时候,要另外分情况插入。

代码如下:

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if(head==NULL) return head;
        //t指向当前待排序元素,pret是t的前驱结点。h当前待插入结点位置,preh是h的前驱结点。
        //一定要有前驱指针。不然执行插入操作之后就会丢失要排序结点的位置了。
        ListNode *h,*preh,*t,*pret;                               
        t=head->next;                       //从第二个结点开始进行插入排序
        pret=head;                             //待排序结点的前驱结点
        while(t){
            if(t->val>=pret->val){           //该元素不需要调整,t指针和前驱指针后移即可
                pret=t;
                t=t->next;
            }else{                           
                if(head->val>=t->val){        //如果插入的位置在头结点之前
                    pret->next=t->next;
                    t->next=head;
                    head=t;
                    t=pret->next;
                }else{                       
                    preh=head;       //从第二个结点开始遍历找到那个大于待排序结点的结点为止。 
                    h=head->next;
                    while(t->val>h->val){
                        preh=h;
                        h=h->next;
                    }
                    //这里就是将待排序结点插入到那个结点的前面。 
                    pret->next=t->next;
                    t->next=h;
                    preh->next=t;
                    t=pret->next;
                }
            }
        }
        return head;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值