力扣(LeetCode) -147 对链表进行插入排序

作者: 小怪兽大作战 | 来源:发表于2019-01-06 22:04 被阅读0次

    本题考察的插入排序和链表操作

    题目描述

    对链表进行插入排序。

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

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

    示例2:
    输入: -1->5->3->4->0
    输出: -1->0->3->4->5

    题目思考

    思路很直观,遍历链表中的每一个结点,通过逐个比较将每个结点插入到正确的位置。注意结点处于开头和结尾等特殊情况。

    代码

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        ListNode myHead;
        public ListNode insertionSortList(ListNode head) {
            ListNode cursor=head;
            myHead=head;
            while(cursor!=null){
                ListNode temp=cursor.next;
                if(temp!=null&&temp.val<cursor.val){  //如果该结点的后一个结点比该节点小
                    cutLink(cursor);  //将后一个结点从链表中取出
                    insertNode(temp,head);  //将后一个结点插入到适合的位置
                }else{
                    cursor=cursor.next;
                }
            }
            return myHead;
        }
        
        public void cutLink(ListNode one){
            ListNode two=one.next;
            ListNode three=two.next;
            one.next=three;
            two.next=null;
        }
        
        public void insertNode(ListNode node,ListNode head){
            ListNode temp=myHead;
            ListNode pre=null;
            while(node.val>temp.val){
                pre=temp;
                temp=temp.next;
            }
            node.next=temp;
            if(pre!=null){
                pre.next=node;
            }else{
                myHead=node;
            }
        }
    }
    

    看了一下别人提交的代码,发现100%的那个代码竟然是用归并排序做的。虽然与题目要求的插入排序不符,但是代码思路挺好的,值得学习一下。下面是归并排序的代码。归并排序的思想先将数据拆分,一直拆分到最小单元。然后将最小单元两两合并,并且排序,得到稍大的有序单元,不断对数据合并,直到将所有数据合并成一个有序序列。示意图如下图所示


    image.png

    代码如下所示

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode insertionSortList(ListNode head) {
            if(head==null||head.next==null)
                return head;
            ListNode fast=head,slow=head,pre=null;
            while(fast!=null&&fast.next!=null){    //将链表二等分
                pre=slow;
                slow=slow.next;
                fast=fast.next.next;
            }
            pre.next=null;   //将链表从中间截断
            ListNode left=insertionSortList(head);    //递归,继续截断链表,直到不可截断
            ListNode right=insertionSortList(slow);    //递归,继续截断链表,直到不可截断
            return merge(left,right);    //对得到的两个短链表进行排序
        }
        
        public ListNode merge(ListNode left,ListNode right){
            if(left==null)
                return right;
            if(right==null)
                return left;
            if(left.val<right.val){
                left.next=merge(left.next,right);
                return left;
            }else{
                right.next=merge(left,right.next);
                return right;
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:力扣(LeetCode) -147 对链表进行插入排序

        本文链接:https://www.haomeiwen.com/subject/tpyerqtx.html