ARTS-2-算法练习-基于链表的归并排序

概述:

左耳朵耗子专栏《左耳听风》 用户自发每周完成一个ARTS:

1.Algorithm:每周至少做一个 leetcode 的算法题

2.Review:阅读并点评至少一篇英文技术文章

3.Tip:学习至少一个技术技巧

4.Share:分享一篇有观点和思考的技术文章

 

Algorithm

题目概述:

Sort a linked list in O(n log n) time using constant space complexity.

 

思路分析:

首先看到关键字空间复杂度为O(n log n)的排序算法,脑海中立马就想到堆排序和快排。但是由于题目是基于链表来实现排序的,因此这个时候只能够使用堆排序来解决该问题。

代码:

package 算法.链表;

/**
 * Sort a linked list in O(n log n) time using constant space complexity.
 * <p>
 * 首先看到这种时间复杂度 需要立马想到归并排序,快速排序
 * 基于链表来实现归并排序
 *
 * @author idea
 * @data 2019/4/11
 */

class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
        next = null;
    }
}

public class MergeSortLinkedTest {

    /**
     * 排序
     *
     * @param head
     * @return
     */
    public static ListNode sortList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode middle = head;
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            middle = slow;
            slow = slow.next;
            fast = fast.next.next;
        }
        //截断链表
        middle.next = null;
        ListNode l1 = sortList(head);
        //slow记录了后半段的头结点
        ListNode l2 = sortList(slow);
        return merge(l1, l2);
    }


    /**
     * 基于链表的核心归并排序
     *
     * @param firstNode
     * @param nextNode
     * @return
     */
    private static ListNode merge(ListNode firstNode, ListNode nextNode) {
        ListNode resultList = new ListNode(0);
        ListNode cur = resultList;
        while (firstNode != null && nextNode != null) {
            if (firstNode.val <= nextNode.val) {
                cur.next = firstNode;
                firstNode = firstNode.next;
            } else {
                cur.next = nextNode;
                nextNode = nextNode.next;
            }
            cur = cur.next;
        }
        if (firstNode != null) {
            cur.next = firstNode;
        }
        if (nextNode != null) {
            cur.next = nextNode;
        }
        //head is not reight node
        return resultList.next;
    }


    public static void main(String[] args) {
        ListNode node = new ListNode(1);
        ListNode node2 = new ListNode(23);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(22);
        ListNode node5 = new ListNode(6);
        ListNode node6 = new ListNode(16);
        node.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        sortList(node);
        while (node != null) {
            System.out.println(node.val);
            node = node.next;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值