排序算法

参考:http://easense2009.iteye.com/blog/1568614
http://www.cnblogs.com/morewindows/archive/2011/08/13/2137415.html
  1 package com.test;
  2 
  3 public class Sort {
  4     public static void main(String[] args) {
  5         Sort p = new Sort();
  6         p.Sort_Quick(p.array, 0, p.array.length);
  7         p.print(p.array);
  8 
  9     }
 10 
 11     public int[] array = { 3, 2, 19, 7, 6, 20 };
 12 
 13     public void print(int[] array) {
 14         for (int i = 0; i < array.length; i++) {
 15             System.out.print(array[i] + ",");
 16         }
 17         System.out.println();
 18     }
 19 
 20     /***
 21      * 选择排序的基本思想是遍历数组的过程中,以 i 代表当前需要排序的序号,则需要在剩余的 [i…n-1] 中找出其中的最小值,然后将找到的最小值与 i
 22      * 指向的值进行交换。因为每一趟确定元素的过程中都会有一个选择最大值的子流程,所以人们形象地称之为选择排序。
 23      * 
 24      * @param array
 25      * @return
 26      */
 27     public int[] Sort_xuanze(int[] array) {
 28         for (int i = 0; i < array.length; i++) {
 29             for (int j = i + 1; j < array.length; j++) {
 30                 if (array[i] > array[j]) {
 31                     int tmp = array[j];
 32                     array[j] = array[i];
 33                     array[i] = tmp;
 34                 }
 35             }
 36         }
 37         return array;
 38     }
 39 
 40     /***
 41      * 冒泡排序可以算是最经典的排序算法了,记得小弟上学时最先接触的也就是这个算法了,因为实现方法最简单,两层 for
 42      * 循环,里层循环中判断相邻两个元素是否逆序
 43      * ,是的话将两个元素交换,外层循环一次,就能将数组中剩下的元素中最小的元素“浮”到最前面,所以称之为冒泡排序。
 44      * 
 45      * 大值元素放后边
 46      * 
 47      * @param array
 48      * @return
 49      */
 50     public int[] Sort_maopao(int[] array) {
 51         for (int i = 0; i < array.length; i++) {// 次数
 52             for (int j = 0; j < array.length - i - 1; j++) {// 两两比较大的放后边
 53                 int a1 = array[j];
 54                 int a2 = array[j + 1];
 55                 if (a1 > a2) {
 56                     int tmp = array[j];
 57                     array[j] = array[j + 1];
 58                     array[j + 1] = tmp;
 59                 }
 60             }
 61         }
 62         return array;
 63     }
 64 
 65     /***
 66      * 插入排序的基本思想是在遍历数组的过程中,假设在序号 i 之前的元素即 [0..i-1] 都已经排好序,本趟需要找到 i 对应的元素 x 的正确位置
 67      * k ,并且在寻找这个位置 k 的过程中逐个将比较过的元素往后移一位,为元素 x “腾位置”,最后将 k 对应的元素值赋为 x
 68      * ,插入排序也是根据排序的特性来命名的。
 69      * 
 70      * @param array
 71      * @return
 72      */
 73     public int[] Sort_Insert(int[] array, int start, int len) {
 74         for (int i = start + 1; i < len; i++) {
 75             int k = -1;
 76             for (int j = start; j < i; j++) {
 77                 if (array[i] < array[j]) {
 78                     k = j;
 79                     break;
 80                 }
 81             }
 82             // k为插入位置
 83             if (k >= 0) {// 移位
 84                 int tmp = array[i];
 85                 for (int p = i - 1; p >= k; p--) {
 86                     array[p + 1] = array[p];
 87                 }
 88                 array[k] = tmp;
 89             }
 90 
 91         }
 92         return array;
 93     }
 94 
 95     /***
 96      * 希尔排序的诞生是由于插入排序在处理大规模数组的时候会遇到需要移动太多元素的问题。希尔排序的思想是将一个大的数组“分而治之”,划分为若干个小的数组,
 97      * 以 gap 来划分,比如数组 [1, 2, 3, 4, 5, 6, 7, 8] ,如果以 gap = 2 来划分,可以分为 [1, 3, 5,
 98      * 7] 和 [2, 4, 6, 8] 两个数组(对应的,如 gap = 3 ,则划分的数组为: [1, 4, 7] 、 [2, 5, 8] 、
 99      * [3, 6] )然后分别对划分出来的数组进行插入排序,待各个子数组排序完毕之后再减小 gap 值重复进行之前的步骤,直至 gap = 1
100      * ,即对整个数组进行插入排序,此时的数组已经基本上快排好序了,所以需要移动的元素会很小很小,解决了插入排序在处理大规模数组时较多移动次数的问题。
101      * 
102      * @param array
103      * @return
104      */
105     public int[] Sort_xier(int[] array) {
106         int gap = 1;
107         while (gap < array.length / 3) {
108             gap = gap * 3 + 1;
109         }
110         while (gap >= 1) {
111             int num = array.length / gap;
112             for (int i = 0; i < gap; i++) {
113                 int len = num;
114                 if (i == gap - 1) {
115                     len = array.length - num * i;
116                 }
117                 Sort_Insert(array, num * i, len);
118             }
119             gap = gap / 3;
120         }
121         return array;
122     }
123 
124     /***
125      * 归并排序采用的是递归来实现,属于“分而治之”,将目标数组从中间一分为二,之后分别对这两个数组进行排序,排序完毕之后再将排好序的两个数组“归并”
126      * 到一起,
127      * 
128      * @param array
129      * @param start
130      * @param len
131      */
132     public void Sort_digui(int[] array, int start, int len) {
133         if (len <= 1) {
134             return;
135         }
136         int mid = start + len / 2;
137         int len1 = len / 2;
138         int len2 = len - len / 2;
139         Sort_digui(array, start, len1);// 前面排序
140         Sort_digui(array, mid, len2);// 后面排序
141         // 合并
142         int[] array1 = new int[array.length];
143         System.arraycopy(array, 0, array1, 0, array.length);
144 
145         int i = 0;
146         int j = 0;
147         int l = 0;
148         while (i < len1 || j < len2) {
149             if (i < len1 && j < len2) {
150                 if (array1[start + i] > array1[mid + j]) {
151                     array[start + l] = array1[mid + j];
152                     j++;
153                 } else {
154                     array[start + l] = array1[start + i];
155                     i++;
156                 }
157             } else if (i < len1) {
158                 array[start + l] = array1[start + i];
159                 i++;
160             } else if (j < len2) {
161                 array[start + l] = array1[mid + j];
162                 j++;
163             }
164             l++;
165         }
166 
167     }
168 
169     /***
170      * 快速排序方法的基本思想是:
171      * <p>
172      * 1.先从数列中取出一个数作为基准数。
173      * <p>
174      * 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
175      * <p>
176      * 3.再对左右区间重复第二步,直到各区间只有一个数。
177      * <p>
178      * 
179      * @param array
180      */
181     public void Sort_Quick(int[] array, int start, int len) {
182         if (len <= 1) {
183             return;
184         }
185         //
186         int[] array1 = new int[array.length];
187         System.arraycopy(array, 0, array1, 0, array.length);
188 
189         // 放入cur
190         int curValue = array[start];
191         int cur = start;
192         int lenPaixu = 1;
193         //开始排序
194         for (int i = start + 1; i < start+len; i++) {
195             if (array1[i] <= curValue) {// 小于cur的 放入cur左边(start 位置)
196                 for (int j = start + lenPaixu - 1; j >= start; j--) {
197                     array[j + 1] = array[j];
198                 }
199                 array[start] = array1[i];
200                 cur++;
201             } else {
202                 array[start+lenPaixu] = array1[i];
203             }
204             lenPaixu++;
205         }
206         
207         Sort_Quick(array, start, cur-start);
208         Sort_Quick(array, cur+1, len-(cur-start)-1);
209 
210     }
211 
212 }

 

posted on 2014-03-06 17:55  wjw334  阅读(186)  评论(1编辑  收藏  举报

导航