• Java排序算法(二)


    java排序算法(二)

    二、改进排序算法

    2.1希尔排序

    定义:希尔排序(ShellSort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。
    希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

    常用的h序列(增量)由Knuth提出,该序列从1开始,通过如下公式产生:h = 3 * h +1

    反过来程序需要反向计算h序列,应该使用h=(h-1)/3

    2.2快速排序

    定义:快速排序(Quicksort)是对冒泡排序的一种改进,是一种非稳定排序。

    快速排序通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

    2.3归并排序

    定义:归并排序(MergeSort)是建立在归并操作上的一种有效的排序算法,该算法是分治法的典型应用。是稳定排序。

    归并排序假设初始序列(数据)有n个记录,看作n个子序列,每个子序列长度为一,然后进行两两归并,得到n/2个长度为2的子序列;让后再两两归并,...,重复操作,最后得到一个长度为n的有序序列,这种方法称为2路归并排序。

    代码如下

      1 public class Sort
      2 {
      3     //实现从小到大排序
      4     public static void main(String[] args)
      5     {
      6         int[] arr1 = {9,1,5,8,3,7,4,6,2};
      7         //quickSort(arr1,0,8);
      8         mergeSort(arr1);
      9         //shellSort(arr1);
     10         for(int i=0;i<arr1.length;i++)
     11         {
     12             System.out.println(arr1[i]);
     13         }
     14     }
     15     /*---------------------------------希尔排序---------------------------------------------
     16     *希尔排序(缩小增量排序),对直接插入排序的改进
     17     *通过加大插入排序中元素之间的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项大框度的移动
     18     *当这些数据项排过一趟序之后,希尔排序算法见效数据项的间隔再进行排序,依次进行下去
     19     *哦爱心时的数据项之间的间隔被称为增量,习惯上用h表示
     20     *常用h序列由Knuth剔除,序列从1开始,通过公式产生h=3*h+1;
     21     *反过来程序反向计算h=(h-1)/3
     22     ---------------------------------------------------------------------------------------*/
     23     public static void shellSort(int[] data)
     24     {
     25         int h=1;
     26         while(h<=data.length/3)
     27         {
     28             h=h*3+1;
     29         }
     30         while(h>0)
     31         {
     32             for (int i = h; i < data.length; i += h) 
     33             {  
     34                 if (data[i] < data[i - h]) 
     35                 {  
     36                     int tmp = data[i];  
     37                     int j = i - h;  
     38                     while (j >= 0 && data[j] > tmp) 
     39                     {  
     40                         data[j + h] = data[j];  
     41                         j -= h;  
     42                     }  
     43                     data[j + h] = tmp;  
     44                     //print(data);  
     45                 }  
     46             }  
     47             // 计算出下一个h值(增量)  
     48             h = (h - 1) / 3;  
     49         }
     50     }
     51     /*---------------------------------快速排序---------------------------------------------
     52     -----------------------------------------------------------------------------------*/
     53     public static void quickSort(int[] arr,int low,int high)
     54     {
     55         if(low<high)
     56         {
     57             int mid = getMid(arr,low,high);
     58             quickSort(arr,0,mid-1);        //递归排序
     59             quickSort(arr,mid+1,high);    
     60         }
     61     }
     62     //取中值
     63     public static int getMid(int[] arr,int low,int high)
     64     {
     65         int key = arr[low];                //基准元素
     66         while(low<high)
     67         {
     68             while(low<high&&arr[high]>=key)    //从high开始找比基准小的元素,如果找到,则互换位置
     69             {
     70                 high--;
     71             }
     72             arr[low] = arr[high];
     73             while(high>low&&arr[low]<=key)    //从low开始找比基准大的,放到之前high空出的位置上
     74             {
     75                 low++;
     76             }
     77             arr[high]=arr[low];
     78         }
     79         arr[low]=key;                //此时low=high是基准元素的位置,也是空出来的那个位置
     80         return low;
     81     }
     82 
     83     /*--------------------------------归并排序------------------------------------
     84     -------------------------------------------------------------------------------*/
     85     public static void mergeSort(int[] data)
     86     {
     87         sort(data,0,data.length-1);
     88     }
     89     public static void sort(int[] data,int left,int right)
     90     {
     91         if(left>=right)
     92         {
     93             return;
     94         }  
     95         int center = (left + right) / 2;          // 找出中间索引 
     96         sort(data, left, center);                // 对左边数组进行递归 
     97         sort(data, center + 1, right);          // 对右边数组进行递归  
     98         merge(data, left, center, right);       // 合并
     99     }
    100      /** 
    101      * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序 
    102      *  
    103      * @param data        数组对象 
    104      * @param left        左数组的第一个元素的索引 
    105      * @param center    左数组的最后一个元素的索引,center+1是右数组第一个元素的索引 
    106      * @param right        右数组最后一个元素的索引 
    107      */  
    108     public static void merge(int[] data, int left, int center, int right) {  
    109         // 临时数组  
    110         int[] tmpArr = new int[data.length];  
    111         // 右数组第一个元素索引  
    112         int mid = center + 1;  
    113         // third 记录临时数组的索引  
    114         int third = left;  
    115         // 缓存左数组第一个元素的索引  
    116         int tmp = left;  
    117         while (left <= center && mid <= right) {  
    118             // 从两个数组中取出最小的放入临时数组  
    119             if (data[left] <= data[mid]) {  
    120                 tmpArr[third++] = data[left++];  
    121             } else {  
    122                 tmpArr[third++] = data[mid++];  
    123             }  
    124         }  
    125         // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)  
    126         while (mid <= right) {  
    127             tmpArr[third++] = data[mid++];  
    128         }  
    129         while (left <= center) {  
    130             tmpArr[third++] = data[left++];  
    131         }  
    132         // 将临时数组中的内容拷贝回原数组中  
    133         // (原left-right范围的内容被复制回原数组)  
    134         while (tmp <= right) {  
    135             data[tmp] = tmpArr[tmp++];  
    136         } 
    137     }  
    138 }
  • 相关阅读:
    Google Earth 使用的经纬度格式及转换
    ADO.NET Entity Framework 一个简单数据绑定例子
    Oracle 异常 ORA01861: literal does not match format string(字符串格式不匹配)
    备份和还原 甲方 Oracle 数据库 问题一大堆
    使用 xsd.exe 命令工具 将 xsd架构 生成 类文件
    简单的源代码统计工具(统计源代码行数、工数、成本、质量指标统计)
    Google KML 起步教程笔记(二)高级 KML 文档与MIME 类型
    SQL Server 2008 中的空间数据存储
    PowerCmd 很好用的命令行工具,也许大家早就知道。
    Google Earth 本地地图缓存文件路径和KML文件路径
  • 原文地址:https://www.cnblogs.com/doStudying/p/6054784.html
Copyright © 2020-2023  润新知