14、排序:插入类排序和交换类排序

  1 package ren.laughing.datastructure.algorithm;
  2 /**
  3  * 排序
  4  * @author Laughing_Lz
  5  * @time 2016年4月22日
  6  */
  7 public class Sorter {
  8     /**
  9      * 直接插入排序(从小到大) 时间复杂度为O(n^2)
 10      * 
 11      * @param arr
 12      *            要排序的数组
 13      * @param low
 14      *            要排序的最低下标
 15      * @param high
 16      *            要排序的最高下标
 17      * @return 排序后的数组
 18      */
 19     public static void insertSort(int[] arr, int low, int high) {
 20         for (int i = low + 1; i <= high; i++) {
 21             int temp = arr[i];// 待插入元素
 22             int j = i;// 记录待插入位置
 23             for (; j > low && temp < arr[j - 1]; j--) {//
 24                 arr[j] = arr[j - 1];// 后移
 25             }
 26             arr[j] = temp;// 插入
 27         }
 28         printResult("直接插入排序:", arr);
 29     }
 30 
 31     /**
 32      * 折半插入排序 时间复杂度仍为O(n^2)
 33      * 
 34      * @param arr
 35      * @param low
 36      * @param high
 37      * @return
 38      */
 39     public static void binInsertSort(int[] arr, int low, int high) {
 40         for (int i = low + 1; i <= high; i++) {
 41             int temp = arr[i];
 42             int lo = low;
 43             int hi = i - 1;
 44             while (lo <= hi) {// 注意'=' ★
 45                 int mid = (lo + hi) / 2;
 46                 if (temp < arr[mid]) {
 47                     hi = mid - 1;// 由此看出最终temp的位置在hi+1
 48                 } else {
 49                     lo = mid + 1;// hi+1等同于lo (此处应该没错吧?)
 50                 }
 51             }
 52             for (int j = i - 1; j > hi; j--) {// 后移
 53                 arr[j + 1] = arr[j];
 54             }
 55             arr[hi + 1] = temp;// 插入
 56         }
 57         printResult("折半插入排序:", arr);
 58     }
 59 
 60     /**
 61      * 希尔排序(缩小增量排序) 当n在某个范围内,时间复杂度可达到O(n^1.3)
 62      * 
 63      * @param arr
 64      * @param low
 65      * @param high
 66      * @param delta
 67      *            步长序列
 68      */
 69     public static void shellSort(int[] arr, int low, int high, int[] delta) {
 70         for (int i = 0; i < delta.length; i++) {// 第一步:遍历步长序列
 71             for (int m = low; m < low + delta[i]; m++) {// 第二步:循环起始点,保证每个被拆分的子序列都被直接排序
 72                 for (int j = m + delta[i]; j <= high; j += delta[i]) {// 对每个子序列直接排序
 73                     int temp = arr[j];
 74                     int k = j;
 75                     for (; k > m && temp < arr[(k - delta[i])]; k -= delta[i]) {
 76                         arr[k] = arr[(k - delta[i])];// 后移
 77                     }
 78                     arr[k] = temp;// 插入
 79                 }
 80             }
 81         }
 82         printResult("希尔排序:", arr);
 83     }
 84 
 85     /**
 86      * 冒泡排序 时间复杂度为O(n^2)
 87      * 
 88      * @param arr
 89      * @param low
 90      * @param high
 91      */
 92     public static void bubbleSort(int[] arr, int low, int high) {
 93         int len = high - low + 1;
 94         for (int i = 1; i < len; i++) {
 95             for (int j = low; j <= high - i; j++) {// 这里j<= high-i ★
 96                 if (arr[j] > arr[j + 1]) {
 97                     int temp = arr[j];// 交换
 98                     arr[j] = arr[j + 1];
 99                     arr[j + 1] = temp;
100                 }
101             }
102         }
103         printResult("冒泡排序:", arr);
104     }
105 
106     /**
107      * 快速排序 需要递归
108      * 
109      * @param arr
110      * @param low
111      * @param high
112      */
113     public static void quickSort(int[] arr, int low, int high) {
114         if (low < high) {
115             int pa = partition(arr, low, high);// 分治
116             quickSort(arr, low, pa - 1);
117             quickSort(arr, pa + 1, high);
118         }
119     }
120 
121     /**
122      * 将序列划分为两个子序列并返回枢轴元素的位置
123      * 
124      * @param arr
125      * @param low
126      *            划分区间
127      * @param high
128      * @return
129      */
130     private static int partition(int[] arr, int low, int high) {
131         int pivot = arr[low];// 首先定义枢轴为low所指元素
132         while (low < high) {// 交替扫描
133             while (arr[high] > pivot && low < high) {
134                 high--;
135             }
136             arr[low] = arr[high];// 将比 pivot 小的元素移向低端
137             while (arr[low] < pivot && low < high) {
138                 low++;
139             }
140             arr[high] = arr[low];// 将比 pivot 大的元素移向高端
141         }
142         arr[low] = pivot;// 设置枢轴
143         return low;
144     }
145 
146     /**
147      * 程序入口
148      * 
149      * @param args
150      */
151     public static void main(String[] args) {
152         int[] arr = new int[] { 2, 5, 7, 3, 4, 8, 1, 9, 6, 0 };
153         int[] delta = new int[] { 5, 3, 1 };
154         // insertSort(arr, 0, 9);
155         // binInsertSort(arr, 0, 9);
156         // shellSort(arr, 0, 9, delta);
157         // bubbleSort(arr, 0, 9);
158         quickSort(arr, 0, 9);
159         printResult("快速排序:", arr);
160     }
161 
162     /**
163      * 打印
164      * 
165      * @param str
166      * @param arr
167      */
168     public static void printResult(String str, int[] arr) {
169         System.out.print(str);
170         for (int i = 0; i < arr.length; i++) {
171             System.out.print(arr[i] + " ");
172         }
173         System.out.println();
174     }
175 }

 

posted @ 2016-04-22 20:47  回看欧洲  阅读(476)  评论(1编辑  收藏  举报