zoukankan      html  css  js  c++  java
  • 算法04 七大排序之:归并排序

    上一篇总结了直接插入排序和希尔排序,这一篇要总结的是归并排序,这也是七大排序的最后一种排序算法。

    首先来看一下归并排序(Merge Sort) 的基本原理。它的原理是假设初始序列有n个元素,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列;再两两归并,…… ,如此重复,直至得到一个长度为n的有序序列为止,这种排序方法就称为归并排序。

    1、归并排序的示意图

    下面用示意图来说明归并排序的过程:

    图一:

    图二:

    2、归并排序的代码

    MergeSort.java 

    public class MergeSort {
        public static void main(String[] args) {
            int[] list = {50, 10, 90, 30, 70};
            System.out.println("************归并排序************");
            System.out.println("排序前:");
            display(list);
            System.out.println("");
    
            System.out.println("排序后:");
            mergeSort(list, new int[list.length], 0, list.length - 1);
            display(list);
        }
    
        /**
         * 归并排序算法
         *
         * @param list     待排序的列表
         * @param tempList 临时列表
         * @param head     列表开始位置
         * @param rear     列表结束位置
         */
        public static void mergeSort(int[] list, int[] tempList, int head, int rear) {
            if (head < rear) {
                // 取分割位置
                int middle = (head + rear) / 2;
                // 递归划分列表的左序列
                mergeSort(list, tempList, head, middle);
                // 递归划分列表的右序列
                mergeSort(list, tempList, middle + 1, rear);
                // 列表的合并操作
                merge(list, tempList, head, middle + 1, rear);
            }
        }
    
        /**
         * 合并操作(列表的两两合并)
         *
         * @param list
         * @param tempList
         * @param head
         * @param middle
         * @param rear
         */
        public static void merge(int[] list, int[] tempList, int head, int middle, int rear) {
            // 左指针尾
            int headEnd = middle - 1;
            // 右指针头
            int rearStart = middle;
            // 临时列表的下标
            int tempIndex = head;
            // 列表合并后的长度
            int tempLength = rear - head + 1;
    
            // 先循环两个区间段都没有结束的情况
            while ((headEnd >= head) && (rearStart <= rear)) {
                // 如果发现右序列大,则将此数放入临时列表
                if (list[head] < list[rearStart]) {
                    tempList[tempIndex++] = list[head++];
                } else {
                    tempList[tempIndex++] = list[rearStart++];
                }
            }
    
            // 判断左序列是否结束
            while (head <= headEnd) {
                tempList[tempIndex++] = list[head++];
            }
    
            // 判断右序列是否结束
            while (rearStart <= rear) {
                tempList[tempIndex++] = list[rearStart++];
            }
    
            // 交换数据
            for (int i = 0; i < tempLength; i++) {
                list[rear] = tempList[rear];
                rear--;
            }
        }
    
        /**
         * 遍历打印
         */
        public static void display(int[] list) {
            System.out.println("********展示开始********");
            if (list != null && list.length > 0) {
                for (int num :
                        list) {
                    System.out.print(num + " ");
                }
                System.out.println("");
            }
            System.out.println("********展示结束********");
        }
    }

    运行结果:

    欢迎转载,但请保留文章原始出处

    本文地址:http://www.cnblogs.com/nnngu/p/8285334.html 

  • 相关阅读:
    网络字节序与主机字节序
    Maven2插件开发详解
    NetBeans 时事通讯(刊号 # 30 Oct 15, 2008)
    NetBeans 时事通讯(刊号 # 30 Oct 15, 2008)
    Grsync:rsync 的图形化界面
    Windows Socket网络编程学习笔记一
    如何调试MFC中的内存泄漏
    内存池(MemPool)技术详解
    These codes are How to use Lucence.net
    VC控制台程序的文字颜色
  • 原文地址:https://www.cnblogs.com/nnngu/p/8285334.html
Copyright © 2011-2022 走看看