zoukankan      html  css  js  c++  java
  • 算法篇---归并排序算法

    归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

    归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

    归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))的额外空间,时间复杂度为O(nlog(n)),算法不是自适应的,不需要对数据的随机读取。

    工作原理:

    1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

    2、设定两个指针,最初位置分别为两个已经排序序列的起始位置

    3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

    4、重复步骤3直到某一指针达到序列尾

    5、将另一序列剩下的所有元素直接复制到合并序列尾

    运行代码

      1 package com.zc.manythread;
      2 
      3 import java.util.Random;
      4 /**
      5  * 归并排序
      6  * @author 偶my耶
      7  *
      8  */
      9 public class MergeSort {
     10 
     11     public static void mergeSort(int[] data) {
     12         sort(data, 0, data.length - 1);
     13     }
     14 
     15     public static void sort(int[] data, int left, int right) {
     16         if (left >= right)
     17             return;
     18         // 找出中间索引
     19         int center = (left + right) / 2;
     20         // 对左边数组进行递归
     21         sort(data, left, center);
     22         // 对右边数组进行递归
     23         sort(data, center + 1, right);
     24         // 合并
     25         merge(data, left, center, right);
     26         print(data);
     27     }
     28 
     29     /**
     30      * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
     31      * 
     32      * @param data
     33      *            数组对象
     34      * @param left
     35      *            左数组的第一个元素的索引
     36      * @param center
     37      *            左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
     38      * @param right
     39      *            右数组最后一个元素的索引
     40      */
     41     public static void merge(int[] data, int left, int center, int right) {
     42         // 临时数组
     43         int[] tmpArr = new int[data.length];
     44         // 右数组第一个元素索引
     45         int mid = center + 1;
     46         // third 记录临时数组的索引
     47         int third = left;
     48         // 缓存左数组第一个元素的索引
     49         int tmp = left;
     50         while (left <= center && mid <= right) {
     51             // 从两个数组中取出最小的放入临时数组
     52             if (data[left] <= data[mid]) {
     53                 tmpArr[third++] = data[left++];
     54             } else {
     55                 tmpArr[third++] = data[mid++];
     56             }
     57         }
     58         // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
     59         while (mid <= right) {
     60             tmpArr[third++] = data[mid++];
     61         }
     62         while (left <= center) {
     63             tmpArr[third++] = data[left++];
     64         }
     65         // 将临时数组中的内容拷贝回原数组中
     66         // (原left-right范围的内容被复制回原数组)
     67         while (tmp <= right) {
     68             data[tmp] = tmpArr[tmp++];
     69         }
     70     }
     71 
     72     public static void print(int[] data) {
     73         for (int i = 0; i < data.length; i++) {
     74             System.out.print(data[i] + "	");
     75         }
     76         System.out.println();
     77     }
     78     /**
     79      * 产生随机数组
     80      * @param count
     81      * @return
     82      */
     83     private static int[]  createDate(int count) {
     84         int[] data=new int[count];
     85           Random rand = new Random();
     86           boolean[] bool = new boolean[100];
     87           int num = 0;
     88           for (int i = 0; i < count; i++) {
     89            do {
     90             // 如果产生的数相同继续循环
     91             num = rand.nextInt(100);
     92            } while (bool[num]);
     93            bool[num] = true;
     94     
     95            data[i]=num;
     96           }
     97           return data;
     98     }
     99     public static void main(String[] args) {
    100         int[] data = createDate(10);
    101         print(data);
    102         mergeSort(data);
    103         System.out.println("排序后的数组:");
    104         print(data);
    105     }
    106 
    107 }

    运行结果:

  • 相关阅读:
    向MySql中插入中文时出现乱码
    MySql插入记录时判断
    SuperGridControl 使用小技巧
    Winform开发中常见界面的DevExpress处理操作
    mysql优化之索引建立的规则
    App性能优化浅谈
    AndroidManifest具体解释之Application(有图更好懂)
    算法——递归思想解决排列组合问题
    Windows App开发之集合控件与数据绑定
    table行随鼠标变色
  • 原文地址:https://www.cnblogs.com/oumyye/p/4202328.html
Copyright © 2011-2022 走看看