链表排序

对链表进行插入排序

对链表进行插入排序。

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

示例 2:

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

public ListNode insertionSortList(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    ListNode cur = head.next;//当前指针
    ListNode pre = head;//前一个指针,用于链接后面的元素
    while (cur != null) {
        if(cur.val>=pre.val){//比前一个大,说明有序了
            cur=cur.next;
            pre=pre.next;
            continue;
        }
        ListNode p=dummy;
        ListNode next=cur.next;//记录next
        while (cur.val>p.next.val){//从头开始找
            p=p.next;
        }
        pre.next=next;//链向遍历过程中的下一个
        cur.next=p.next;//插入
        p.next=cur;
        cur=next;
    }
    return dummy.next;
}

从头开始比较

public ListNode insertionSortList(ListNode head) {
    ListNode dummy = new ListNode(0);
    ListNode cur = head;
    while (cur != null) {
        ListNode next = cur.next;
        ListNode p = dummy;
        while (p.next != null && p.next.val < cur.val) {
            p = p.next;
        }
        if (p.next != null) {//插入到已经有序链表的中间
            cur.next = p.next;
        } else {//插入到已经有序的链表的末尾
            cur.next = null;
        }
        p.next = cur;
        cur = next;
    }
    return dummy.next;
}

一点优化:

public ListNode insertionSortList(ListNode head) {
    ListNode dummy = new ListNode(0);
    ListNode cur = head;
    ListNode pre = dummy;//记录已经有序的链尾,即最大的元素
    while (cur != null) {
        ListNode next = cur.next;
        if (cur.val >= pre.val) {//比最大的还大,直接链在链尾
            pre.next = cur;
            cur.next = null;
            pre = cur;
            cur = next;
            continue;
        }
        ListNode p = dummy;
        while (p.next != null && p.next.val < cur.val) {
            p = p.next;
        }
        if (p.next != null) {
            cur.next = p.next;
        } else {
            cur.next = null;
            pre = cur;
        }
        p.next = cur;
        cur = next;
    }
    return dummy.next;
}
排序链表

O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序

归并排序:

public ListNode sortList(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    ListNode mid = middleNode(head);
    ListNode rightHead = mid.next;
    mid.next = null;
    ListNode left=sortList(head);
    ListNode right=sortList(rightHead);
    return merge(left,right);
}

//返回链表终点
public ListNode middleNode(ListNode head) {
    if (head == null || head.next == null) {
        return head;
    }
    ListNode slow = head;
    ListNode fast = head.next.next;
    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow;
}


public ListNode merge(ListNode head1, ListNode head2) {
    ListNode p1 = head1;
    ListNode p2 = head2;
    ListNode newHead = new ListNode(0);
    ListNode p = newHead;
    while (p1 != null && p2 != null) {
        if (p1.val <= p2.val) {
            p.next = p1;
            p1 = p1.next;
        } else {
            p.next = p2;
            p2 = p2.next;
        }
        p = p.next;
    }
    if(p1!=null){
        p.next=p1;
    }
    if(p2!=null){
        p.next=p2;
    }
    return newHead.next;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值