单链表的排序

单链表的排序

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

相关推荐

ProMonkey2024:5个oc?厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了(别的帖子偷来的,现学现卖😋)
点赞 评论 收藏
分享
冲芭芭拉鸭:你这图还挺新,偷了。
投递美团等公司10个岗位
点赞 评论 收藏
分享
点赞 评论 收藏
分享
17 1 评论
分享
牛客网
牛客企业服务