数据结构之高级排序算法

一、希尔排序

希尔排序(缩小增量法) 属于插入类排序,由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 }
posted @ 2016-04-23 21:57  菜鸟奋斗史  阅读(816)  评论(0编辑  收藏  举报