zoukankan      html  css  js  c++  java
  • [原创]二路归并排序针对单向链表的场景(java版)

    二路归并排序最常用的场景是数组,那么如果数据结构采用单向链表呢?如何实现?

    基本思想是一样的,对比数组场景,需要注意一下几点:

    ①在合并阶段:merge(..)合并两个已经有序的链表时,要比数组更简单些;

    ②在递归调用阶段:mergeSort(...),在该方法里,和数组一样需要确定中间位置,然后分为两半,对这两半分别进行递归调用二路归并排序,

     然后得到两个已经排好序的单向链表,最后对这两个单向链表进行合并;

     需要注意之处在于,单链表时,需要将一个单链表拆分成两个单链表,中间的next指针联系需要断开,否则在merge的时候会形成环,从而导致无限循环下去;

     ③该单链表的场景,时间复杂度还是O(N*log2N),但空间复杂度从O(n)减为了O(1);

    具体代码如下:

      //合并阶段:合并两个已经排好序的单向链表
      private ListNode merge(ListNode head1, ListNode head2) {
            ListNode head = new ListNode(0);
            ListNode p = head;
            ListNode p1 = head1;
            ListNode p2 = head2;
            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;
            }
            while (p1 != null) {
                p.next = p1;
                p1 = p1.next;
                p = p.next;
            }
            while (p2 != null) {
                p.next = p2;
                p2 = p2.next;
                p = p.next;
            }
            p.next = null;
            return head.next;
        }
      //递归调用阶段  private ListNode mergeSort(ListNode low, ListNode high, int n) { ListNode head = low; ListNode leftH = null; ListNode rightH = null; if (low != high) { ListNode mid = getIndexof(low, n / 2); //注意这里将其拆分为了两个链表,必须将两个链表之间的联系进行断开,否则会无线循环 ListNode midNext = mid.next; mid.next = null; leftH = mergeSort(low, mid, n / 2); rightH = mergeSort(midNext, high, n - n / 2); head = merge(leftH, rightH); } return head; }
      //辅助函数,从low结点出发,返回第n个结点位置(包括low结点) private ListNode getIndexof(ListNode low, int n) { ListNode p = low; while (n-- != 1) { p = p.next; } return p; }   //通过调用归并排序mergeSort(..)进行排序单链表   //这里为了确定该单向链表最后一个结点以及结点总数,进行了遍历,但这并不影响时间复杂度为O(N*log2N)   public ListNode sortList(ListNode head) { if (head == null || head.next == null) return head; int n = 1; ListNode p = head; while (p.next != null) { p = p.next; n++; } return mergeSort(head, p, n);   }

      

  • 相关阅读:
    Android开发——Activity启动模式详解
    Spring核心技术(十一)——基于Java的容器配置(一)
    【数学】控制论
    【Mongo】聚合函数
    【Deeplearning】blog
    【Python】添加注册表信息脚本
    【数据库】备份与恢复
    【MongoDB】数组长度查询
    【Mysql】修改最大连接数
    【Python】多线程2
  • 原文地址:https://www.cnblogs.com/lordcheng/p/7326584.html
Copyright © 2011-2022 走看看