leecode 归并排序 链表(java)

写了好久,终于写成了.第一次zai leecode错题,题目质量很高,适合面试,与

1.归并排序是稳定的,在java中 Arrays.sort(a);中对于对象的排序就是归并排序。对于原子类型数据使用的是快排。

2.算法复杂度,我们都知道归并排序的最好最坏最差复杂度为nlogn,空间复杂度为n,在链表当中,空间复杂度j降为O(1)。

3.写链表的排序

1.分: 使用书上的快慢指针来获得中间节点,分割成2个链表

2.和: 将两个链表合成一个,比较简单

3.

主程序

ListNode lmerge(ListNode list)

{

if(list==null)  return  null;//如果是空链表

if(list.next==null) return list;//单个节点

//以下是多节点的情况

1分割 返回中间的地址   middle=split(head)

return (middle,head); 、、 返回连接后的地址

}

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

public class LinklistSort {

    public static ListNode create(int a[])
    {
      ListNode head=new ListNode(a[0]);
      for(int i=1;i<a.length ;i++)
      {
          ListNode node=new ListNode(a[i]);
          node.next=head.next;
          head.next=node;

      }
      return head;

    }
    public static void display(ListNode head)
    {
        ListNode list=head;
        while(list!=null)
        {

            System.out.print(list.val+"--");
            list=list.next;

        }
        System.out.println();

    }

   public static ListNode sortList(ListNode head) {
       //没有一个节点
       if(head==null) return null;
       //有一个节点
       if(head.next==null) return head;
       //有两个以上的节点

       ListNode middle=split(head);

       return merge(sortList(head),sortList(middle));

    }

    private static ListNode merge(ListNode head, ListNode middle) {

        ListNode p1=head;
        ListNode p2=middle;
        ListNode h=new ListNode(-1);//一个new头
        ListNode tail=h;

        while(p1!=null&&p2!=null)
        {
            if(p1.val<=p2.val)
            {

                tail.next=p1;
                tail=tail.next;
                p1=p1.next;

            }
            else
            {
                tail.next=p2;
                tail=tail.next;

                p2=p2.next;

            }

        }

        if(p1!=null)
        {
            tail.next=p1;

        }
        if(p2!=null)
        {
            tail.next=p2;
        }

        return h.next ;
}
    //分成两部分的部分
    private static ListNode split(ListNode head) {
        ListNode quick=head;
        ListNode slow=head;
        ListNode pre=null;
        while(quick!=null)
        {
            pre=slow;
            slow=slow.next;
            quick=quick.next;
            if(quick!=null) quick=quick.next ;

        }
        pre.next =null;
    return slow;
}
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int a[]={1,3,-5,8,56,44,56};
         ListNode list=create(a);
        // display(list);
         ListNode l=sortList(list);

         display(l);

    }

}

leecode 归并排序 链表(java)

时间: 2024-07-30 10:06:48

leecode 归并排序 链表(java)的相关文章

单链表java简易实现

巩固数据结构 单链表java实现 单链表除了表尾 每个几点都有一个后继 结点有数据和后继指针组成  通过构建表头和表尾(尾部追加需要)两个特殊几点 实现单链表的一些操作,代码如下 package com.shine.test.datastruct; /** * 简易链表 * * @author SHINE * * @param <E> */ public class LinkList<E> { private Node head, tail; private int size =

单向链表的归并排序(Java)

Sort a linked list in O(n log n) time using constant space complexity. 1 package SortList; 2 3 import java.util.Iterator; 4 5 class ListNode { 6 7 int val; 8 ListNode next; 9 ListNode(int val) { 10 this.val = val; 11 } 12 } 13 14 public class Solutio

归并排序算法--java

归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为2-路归并. 归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))

java数据结构之链表(java核心卷Ⅰ读书笔记)

1.链表 数组和ArrayList的一个重大缺陷就是:从中间位置删除一个元素要付出很大的代价,因为在这个元素删除之后,所有的元素都要向前端移动,在中间的某个位置插入一个元素也是这个原因. (小感悟:sun-zheng说了一句,每天在那安静地写代码,才是最轻松的活,不用这跑那跑,不用费太多的口舌,每天吹着空调,外面就是建筑地,别人风吹日赛,真的写代码是一件最轻松的事情) 我们在数据结构这门课中,在链表中添加或者删除某个元素时候,绕来如去的指针可能已经给人留下了极坏的印象,那么Java的集合类库提供

排序算法入门之归并排序(java实现)

归并排序是采用分治法的典型应用. 参考<数据结构与算法分析-Java语言描述> 归并排序其实要做两件事: (1)"分解"--将序列每次折半划分. (2)"合并"--合并两个已排序的表. 合并:对于两个输入数组A和B,一个输出数组C,以及3个计数器Actr.Bctr.Cctr,他们的初始置于对应数组的开始端.A[Actr]和B[Bctr]中较小的拷贝到C中的下一个位置,相关的计数器向前推进一步.当两个输入表有一个用完时,则将另一个表中剩余的部分拷贝到C中.

归并排序算法-Java实现

简介: 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序 基本思想: 将一个无序数组,利用递归和分治的方法划分为最小半子集,最终划分为完全二叉树.然后对半子集进行排序并进行递归合并到最后. 复杂度分析: 时间复杂度为O(nlogn)  空间复杂度为O(n+logn)  两两比较,不存在跳跃,因此归并排序是一种稳定的排序算法  归并排序是一种比较占内存,但却效率高且稳定的算法 工作原理 (

[C++]LeetCode: 125 Sort List (归并排序链表)

题目:Sort a linked list in O(n log n) time using constant space complexity. 思路:题目要求我们使用常数空间复杂度,时间复杂度为O(nlog(n)). 满足这个时间复杂度的有快速排序,归并排序,堆排序.插入排序时间复杂度为O(n^2). 双向链表用快排比较合适,堆排序也可用于链表,单项链表适合于归并排序.我们就用归并排序的思想来完成链表的排序. 首先是用快慢双指针找到链表中间的位置,然后分成前后端分别递归的归并排序,最后合并.

剑指offer-从尾到头打印链表 java实现

题目描述: 输入一个链表,从尾到头打印链表每个节点的值. 代码实现: /** * public class ListNode { * int val; * ListNode next = null; * * ListNode(int val) { * this.val = val; * } * } * */ import java.util.ArrayList; import java.util.Stack; public class Solution { public ArrayList<In

leetcode合并两个有序链表Java实现

将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4 两个有序链表的排序,实际上可以看成一个单链表使用归并排序的最后一个环节:“将两个排好序的子序列合并为一个子序列:每次都是从未比较的两个子序列的最小值中选出一个更小值”. /** * Definition for singly-linked list. * public cl