刷题No24. sort-list(排序)(java)【链表】

血红的双手。 提交于 2020-02-11 19:05:44

题目:在O(n log n)的时间内使用常数级空间复杂度对链表进行排序。

思路:由于题目要求,时间复杂度要求为O(n log n),所以,需要用归并排序。

  • 找到链表的中间节点
  • 通过中间节点将链表1分为2
  • 两个链表进行比较,比较完之后进行合并。

代码:

package com.company;

import java.util.List;

public class TestNo24 {
    //定义单链表
    static class ListNode{
        int val;
        ListNode next;
        ListNode(int x){
            val = x;
            next = null;
        }
        public String toString(){
            if(this.next == null){
                return String.valueOf(this.val);
            }
            return this.val + "->" + this.next.toString();
        }
    }
    public static void main(String[] args) {
        TestNo24 t = new TestNo24();
        ListNode head = new ListNode(4);
        head.next = new ListNode(5);
        head.next.next= new ListNode(7);
        head.next.next.next = new ListNode(9);
        head.next.next.next.next = new ListNode(10);
        head.next.next.next.next.next = new ListNode(1);
        head.next.next.next.next.next.next = new ListNode(2);
         // 下面是产生连续的链表
//        ListNode head = createTestLinkList();
//        ListNode newHead = new ListNode(13);
        //newHead.next = head;
        System.out.println(head);
        System.out.println(t.sortList(head));


    }
    private  static ListNode createTestLinkList(){
        ListNode head = new ListNode(0);
        ListNode curNode = head;
        for(int i = 0;i<10;i++){
            curNode.next = new ListNode(i);
            curNode = curNode.next;
        }
        return head;

    }
    public ListNode sortList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode mid = getMid(head);
        ListNode another ;
        if(mid == null){
            another = null;
        }else{
            //此时是两个链表,从链表的中间节点分开,中间节点之前之后分别是一个链表
            another = mid.next;
            mid.next = null;
        }
        return mergeSortedList(sortList(head),sortList(another));
    }
    //合并两个有序链表为一个链表
    private ListNode mergeSortedList(ListNode first,ListNode second){
        if(first == null && second == null){
            return null;
        }
        if(first == null){
            return second;
        }
        if(second == null){
            return first;
        }
        //虚拟一个head的前缀节点
        ListNode pre = new ListNode(0);
        ListNode curNode = pre;

        ListNode cur1 = first;
        ListNode cur2 = second;
        while (cur1 != null && cur2 !=null){
            if(cur1.val <= cur2.val){
                curNode.next = cur1;
                cur1 = cur1.next;
            }else{
                curNode.next = cur2;
                cur2 = cur2.next;
            }
            curNode = curNode.next;
        }
        //处理剩下的节点元素
        if(cur1 != null){
            curNode.next = cur1;
        }else{
            curNode.next = cur2;
        }
        return pre.next;

    }
    //寻找链表的中间节点,使用快慢两个指针
    private ListNode getMid(ListNode head){
        if(head == null || head.next == null){
            return head;
        }
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next != null && fast.next.next !=null){
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
}

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!