zoukankan      html  css  js  c++  java
  • 归并排序单链表实现

    /**
     * Project Name:Algorithm
     * File Name:SingleListMergeSort.java
     * Package Name:
     * Date:2017年9月22日上午10:08:46
     * Copyright (c) 2017, 2692613726@qq.com All Rights Reserved.
     *
     */
    
    /**
     * ClassName:SingleListMergeSort 
     * Function: 链表实现归并排序
     * Reason:    (1)定义链表结构 
     *             (2)链表的关键在于递归的时候中间位置的确定,方法是:用两个指针slow,fast 遍历链表,slow走一步而fast走两步;当fast走完的时候slow走到链表的一半!
     *             (3)时间复杂度为O(nlgn),空间复杂度为O(1)   
     * Date:     2017年9月22日 上午10:08:46 
     * @author   michael
     * @version  
     * @since    JDK 1.7
     * @see      
     */
    public class MergeSortSingle {
        //先找到中间点,然后分割
        public ListNodes getMiddle(ListNodes head){
            if(head == null){
                return head;
            }
            //定义快慢指针
            ListNodes slow, fast;
            slow=fast=head;
            while(fast.next!=null&&fast.next.next!=null){
                slow = slow.next;
                fast = fast.next.next;
            }
            return slow;
        }
        public ListNodes merge(ListNodes a, ListNodes b){
            //dummyHead是一个新的链表
            //将dummyHead的头节点赋值给curr,curr往后遍历,而dummyHead还是指向头节点
            ListNodes dummyHead,curr;
            dummyHead = new ListNodes(0);
            curr = dummyHead;
            while (a!=null&&b!=null) {
                if(a.val<b.val){
                    curr.next=a;
                    a = a.next;
                }else {
                    curr.next = b;
                    b = b.next;
                }
                //curr往后移动
                curr = curr.next;
            }
            //如果a遍历完,则将b剩下的部分赋值给curr
            curr.next = (a!=null)?a:b;
            return dummyHead.next;
        }
        public ListNodes merge_sort(ListNodes head){
            if(head==null||head.next==null){
                return head;
            }
            //取链表中间节点,作为前部分的最后一个节点
            ListNodes middle = getMiddle(head);
            //中间节点的下一个节点,作为后部分的后一个节点
            ListNodes halfHead = middle.next;
            //分:在中间节点处断开
            middle.next=null;
            //合:
            return merge(merge_sort(head), merge_sort(halfHead));
        }
    
        public static void main(String[] args) {
            ListNodes head = new ListNodes(0);
            ListNodes l1 = new ListNodes(2);
            ListNodes l2 = new ListNodes(5);
            ListNodes l3 = new ListNodes(3);
            ListNodes l4 = new ListNodes(8);
            ListNodes l5 = new ListNodes(5);
            ListNodes l6 = new ListNodes(2);
            ListNodes l7 = new ListNodes(1);
    
            head.next = l1;
            l1.next = l2;
            l2.next = l3;
            l3.next = l4;
            l4.next = l5;
            l5.next = l6;
            l6.next = l7;
            l7.next = null;
    
            ListNodes p = head;
            while (p.next != null) {
                System.out.print(p.val);
                p = p.next;
            }
            System.out.print(p.val);
            System.out.println();
            new MergeSortSingle().merge_sort(head);
            
            p = head;
            while(p!=null){
                System.out.print(p.val);
                p = p.next;
            }
        }
    }
    
    class ListNodes{
        //节点的值
        int val;
        //连接到下一个节点
        ListNodes next;
        
        public ListNodes(int x) {
            val = x;
            next = null;
        }
    }

  • 相关阅读:
    C#值类型和引用类型的不同
    C# new用法总结-转
    C#中New关键词的几种用法
    命令行客户端MySQL的使用(1)——Python
    数据库的基本使用——MySQL
    生成器的创建方式——Python
    with与“上下文管理器”——Python
    魔法属性——Python
    property属性——Python
    正则匹配之贪婪和非贪婪——Python
  • 原文地址:https://www.cnblogs.com/Michael2397/p/7577416.html
Copyright © 2011-2022 走看看