单链表的排序

单链表的排序

http://www.nowcoder.com/questionTerminal/f23604257af94d939848729b1a5cda08

链表的特点决定了只能从前往后的遍历,我的第一个思路是冒泡排序,但是超时,看了一眼归并排序的写法,真的是妙啊。

1 冒泡(未通过)

    public ListNode sortInList (ListNode head) {
        // write code here
        ListNode res=null;
        if(head==null){
            return res;
        }
        int nodeNum=0;
        ListNode p=head;
        while(p!=null){ //遍历链表获得链表节点数,节点数是用来控制沉降次数,9个节点,沉降8次
            nodeNum++;
            p=p.next;
        }
        for(int i=nodeNum-1;i>0;i--){
            int count=i; //控制这一次沉降的结束边界,后面的就不用沉降了已经是有序了
            ListNode p1=head;
            ListNode p2=head.next;
            while(count>0){
                if(p1.val>p2.val){//值交换
                    int tmp=p1.val;
                    p1.val=p2.val;
                    p2.val=tmp;
                }
                p1=p1.next;
                p2=p2.next;
                count--;
            }
        }
        res=head;
        return res;
    }

2 归并排序


public ListNode sortInList (ListNode head) {
    // write code here
    ListNode res=null;
    if(head==null){
        return res;
    }
    return mergeSort(head);
}
public ListNode mergeSort(ListNode head){
    if(head==null || head.next==null){ //最后没有节点或者最后还有一个节点,返回本身,一个节点本身就是有序了,不用排了
        return head;
    }
    ListNode slow=head;
    ListNode fast=head.next.next; //上面已经排除了1个节点的请情况,所以这里至少有两个节点,head.next.next 存在
    ListNode head1=head;
    while(fast!=null && fast.next!=null){ //两个节点不用进去循环,假如我们让进去循环的话,fast为null,fast.next 作为条件就报错。
        slow=slow.next;
        fast=fast.next.next;
    }
    ListNode head2=slow.next; //先保存后面链表的头节点
    slow.next=null;//将前面链表断开形成真正的两条链表
    ListNode left=mergeSort(head1);
    ListNode right=mergeSort(head2);
    return mergeList(left,right);
}
public ListNode mergeList(ListNode l1,ListNode l2 ){//这里比较巧妙,这是一个针对有序链表的写法,但是我们的拆分明明是不能保证有序的,哈哈,巧在当我们在不停的分治的过程中,最后一定是有单节点的合并的,两个单节点可以认为就是两个有序的链表,两个单节点的合并就是两个有序链表的合并,也就是说两个单节点链表合并成了一个拥有两个节点的有序链表,再继续向上回溯,从下网上就形成了两个有序链表的合并了。
    ListNode node=new ListNode(0);
    ListNode p=node;
    while(l1!=null||l2!=null){
        if(l1!=null && l2!=null){
            if(l1.val<l2.val){
                p.next=l1;
                l1=l1.next;
                p=p.next;
            }else{
                p.next=l2;
                l2=l2.next;
                p=p.next;
            }
        }else if(l1==null){
                p.next=l2;
                l2=l2.next;
                p=p.next;
        }else if(l2==null){
                p.next=l1;
                l1=l1.next;
                p=p.next;
        }
    }
    return node.next;
}
全部评论
我冒泡过了,后面想想用辅助数组也可以快排,最后试了一下归并
点赞 回复
分享
发布于 2022-02-28 12:08

相关推荐

17 1 评论
分享
牛客网
牛客企业服务