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);   }

      

  • 相关阅读:
    vue-quill-editor 注册行高样式
    vue-quill-editor + + antd 组件封装(包含图片上传)
    uniapp
    unipp
    uniapp
    uniapp
    简单实现数据双向绑定
    使用canvas + hammer.js 手势库 制作海报
    如何在jquery 中动态添加 !important 样式
    基于极光 实现在线聊天
  • 原文地址:https://www.cnblogs.com/lordcheng/p/7326584.html
Copyright © 2011-2022 走看看