zoukankan      html  css  js  c++  java
  • 数据结构之高级排序算法

    一、希尔排序

    希尔排序(缩小增量法) 属于插入类排序,由Shell提出,希尔排序对直接插入排序进行了简单的改进:它通过加大插入排序中元素之间的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项大跨度地移动,当这些数据项排过一趟序之后,希尔排序算法减小数据项的间隔再进行排序,依次进行下去,进行这些排序时的数据项之间的间隔被称为增量,习惯上用字母h来表示这个增量。

    具体代码实现:

     1 package data.struct.algorithm;
     2 
     3 //高级排序算法之希尔排序
     4 class ArraySh {
     5     private int[] arr;
     6     private int nItems;
     7 
     8     public ArraySh(int maxSize) {
     9         arr = new int[maxSize];
    10         nItems = 0;
    11     }
    12 
    13     public void insert(int value) {
    14         arr[nItems++] = value;
    15     }
    16 
    17     // 显示数组内容
    18     public void displayArr() {
    19         for (int j = 0; j < nItems; j++) {
    20             System.out.print(arr[j] + " ");
    21         }
    22         System.out.println();
    23     }
    24 
    25     // 希尔排序
    26     public void shellSort() {
    27         // h的定义是:希尔排序的增量值
    28         int h = 1;
    29         int temp;
    30         int j;
    31         // 记录排序的次数
    32         int times = 0;
    33         /*
    34          * 常用的h序列由Knuth提出,该序列从1开始,通过如下公式产生: h = 3 * h +1 ;反过来程序需要反向计算h序列,应该使用
    35          * h=(h-1)/3
    36          */
    37         while (h < nItems / 3) {
    38             h = 3 * h + 1;
    39         }
    40         while (h > 0) {
    41             // 每个相同增量的子序列,希尔排序与直接插入排序的结合
    42             for (int i = h; i < nItems; i += h) {
    43                 if (arr[i] < arr[i - h]) {
    44                     temp = arr[i];
    45                     j = i - h;
    46                     while (j >= 0 && arr[j] > temp) {
    47                         arr[j + h] = arr[j];
    48                         j -= h;
    49                     }
    50                     arr[j + h] = temp;
    51                     System.out.println("第" + (++times) + "次排序");
    52                     displayArr();
    53                 }
    54             }
    55             // 计算下一个h的值
    56             h = (h - 1) / 3;
    57         }
    58     }
    59 }
    60 
    61 public class ShellSortTest {
    62 
    63     /**
    64      * @param args
    65      */
    66     public static void main(String[] args) {
    67         int maxSize = 10;
    68         ArraySh arraySh = new ArraySh(maxSize);
    69         for (int j = 0; j < maxSize; j++) {
    70             // 随机产生数组的元素
    71             arraySh.insert((int) (Math.random() * 99));
    72         }
    73         arraySh.displayArr();
    74         System.out.println("---希尔排序步骤--");
    75         arraySh.shellSort();
    76     }
    77 
    78 }

    运行结果:

    15 42 58 60 78 98 68 3 25 46 
    ---希尔排序步骤--
    第1次排序
    15 42 58 60 25 98 68 3 78 46 
    第2次排序
    15 25 42 58 60 98 68 3 78 46 
    第3次排序
    15 25 42 58 60 68 98 3 78 46 
    第4次排序
    3 15 25 42 58 60 68 98 78 46 
    第5次排序
    3 15 25 42 58 60 68 78 98 46 
    第6次排序
    3 15 25 42 46 58 60 68 78 98 

    希尔排序的效率分析

    上面程序在和直接插入法比较,会发现其与直接插入排序的差别在于:直接插入排序中的h会以1代替

    Shell排序是不稳定的排序算法,它的空间复杂度是O(1),时间开销估计在O(N3/2)~O(N7/6)之间

    二、快速排序

    快速排序(Quicksort)是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递递归进行,以此达到整个数据变成有序序列。

    具体代码实现:

     1 package data.struct.algorithm;
     2 
     3 public class QuickSortTest {
     4 
     5     /**
     6      * @param args
     7      */
     8     public static void main(String[] args) {
     9         int arr[] = new int[10];
    10         for (int j = 0; j < arr.length; j++) {
    11             arr[j] = (int) (Math.random() * 99);
    12         }
    13         System.out.println("----排序前----");
    14         displayArr(arr);
    15         quickSort(arr, 0, arr.length - 1);
    16         System.out.println("----排序后----");
    17         displayArr(arr);
    18 
    19     }
    20 
    21     public static void quickSort(int arr[], int start, int end) {
    22         if (arr == null || end - start + 1 < 2) {
    23             return;
    24         } else {
    25             if (start < end) {
    26                 int pivotKey = Partition(arr, start, end);
    27                 quickSort(arr, start, pivotKey - 1);
    28                 quickSort(arr, pivotKey + 1, end);
    29             }
    30         }
    31     }
    32 
    33     // 划分算法:通过一趟排序减法待排记录分割成队里的两部分,一部分关键字都小于枢纽值(pivotKey),另一比分都大于枢纽值(pivotKey)
    34     public static int Partition(int[] arr2, int low, int high) {
    35         // 此处的划分算法,我们假定总是选择数组最左端的元素作为枢纽值
    36         int temp = arr2[low];
    37         while (low < high) {
    38             while (low < high && arr2[high] > temp) {
    39                 high--;
    40             }
    41             arr2[low] = arr2[high];
    42             while (low < high && arr2[low] < temp) {
    43                 low++;
    44             }
    45             arr2[high] = arr2[low];
    46         }
    47         arr2[low] = temp;
    48         return low;
    49     }
    50 
    51     public static void displayArr(int arr[]) {
    52         for (int j = 0; j < arr.length; j++) {
    53             System.out.print(arr[j] + " ");
    54         }
    55         System.out.println();
    56     }
    57 
    58 }
  • 相关阅读:
    java基础之java今生前世
    java线程的方便调用方式
    await和async更多的理解
    asp.net mvc webapi 实用的接口加密方法
    微信小程序开发心得
    为IEnumerable<T>添加RemoveAll<IEnumerable<T>>扩展方法--高性能篇
    微软常用的组件设计思想-‘工厂的工厂类’
    尝试asp.net mvc 基于controller action 方式权限控制方案可行性
    cookie 和session 详解
    sql注入详解
  • 原文地址:https://www.cnblogs.com/ysw-go/p/5425794.html
Copyright © 2011-2022 走看看