1 package com.amazonaws.mws.test;
2
3 import java.util.Arrays;
4
5 public class SortTest {
6
7 public static void main(String[] ss) {
8
9 int[] arr = {9, 2, 8, 6, 5, 4, 7, 1, 5, 8, 2, 6, 4, 1,};
10 System.out.println(Arrays.toString(arr));
11 baseSort(arr);
12 System.out.println(Arrays.toString(arr));
13
14 }
15
16
17 /**
18 * 基数排序
19 * 此种方法是:通过对个位、十位、百位。。。的依次比较排序,然后决定最终排序
20 * @param arr 排序的数组
21 */
22 private static void baseSort(int [] arr){
23 int[][] ints = new int[10][arr.length];
24 int[] ab = new int[10];
25 int maxElement = Integer.MIN_VALUE;
26 for (int i2 : arr) {
27 if (i2 > maxElement)
28 maxElement = i2;
29 }
30 int time = String.valueOf(maxElement).length();
31 int index;
32
33 for(int i = 0; i < time; i ++){
34 for (int i1 : arr) {
35 int ind = i1 / (i + 1) % 10;
36 ints[ind][ab[ind]] = i1;
37 ab[ind]++;
38 }
39 index = 0;
40 for(int k = 0;k<ab.length;k++){
41 if(ab[k] > 0){
42 for(int l = 0;l < ab[k];l++){
43 arr[index] = ints[k][l];
44 index ++;
45 }
46 ab[k] = 0;
47 }
48 }
49 }
50 }
51
52 /**
53 * 使用归并排序
54 * 如果我们要对两个已经排好序的数组进行合并,并且要求合并后的依然是排序的。
55 * 以上要求可以如此考虑,我们先创建一个等于两个数组长度之和的新数组,依次将两个数组从低位进行比较,将比较小的那个数据插入新的数组,知道某一个数组为空(或者全部插入)
56 * 再将另一个数组剩余部分补位到新数组后面。这样两个数组的重新排序就完成了。
57 * 当我们拿到一个乱序数组的时候,将数组不断细分,当分隔到每一个部分只有一个元素的时候,该子数组一定有序(只有一个元素),再将这些子数组依次合并排序,直到最后的数组完成排序.
58 *
59 * @param arr 传入数组
60 * @param start 需要排序的初始位置
61 * @param end 需要排序的结束位置
62 * @return 排序后的数组
63 */
64 private static int[] mergeSort(int[] arr, int start, int end) {
65 if (start >= end)
66 return new int[]{arr[start]};
67
68 int mid = (start + end) / 2;
69
70 int[] leftArr = mergeSort(arr, start, mid);
71 int[] rightArr = mergeSort(arr, mid + 1, end);
72 int[] newArr = new int[leftArr.length + rightArr.length];
73 int l = 0;
74 int r = 0;
75 int n = 0;
76 while (l < leftArr.length && r < rightArr.length) {
77 newArr[n++] = leftArr[l] < rightArr[r] ? leftArr[l++] : rightArr[r++];
78 }
79 while (l < leftArr.length){
80 newArr[n++] = leftArr[l++];
81 }
82 while (r < rightArr.length){
83 newArr[n++] = rightArr[r++];
84 }
85 return newArr;
86 }
87
88
89 /**
90 * 选择排序:定义一个最小数据所在下标的 变量。
91 * 先拿到数组最前列的数据,认为该数据就是最小数据,将其下标记录到上述变量中,然后使用该下标中的值依次向后比较,当碰到值比其小的,就将下标替换成新值的下标。
92 * 当第一次比较过后,上述下标变量一定指向最小的元素的下标,将该下标上的值与第一个位置互换。
93 * 之后认为第二个下标是剩下数据最小值,重复上述过程
94 *
95 * @param arr 排序数组
96 */
97 private static void choiceSort(int[] arr) {
98 for (int i = 0; i < arr.length; i++) {
99 int index = i;
100 for (int j = i + 1; j < arr.length; j++) {
101 if (arr[index] > arr[j]) {
102 index = j;
103 }
104 }
105 int temp = arr[index];
106 arr[index] = arr[i];
107 arr[i] = temp;
108 }
109 }
110
111
112 /**
113 * 希尔排序是以跨度分组的方式多次使用插入排序,下面代码中里面的两个for循环,如果当 的d = 1的时候,就是一个标准的插入排序了。
114 * 希尔排序是在插入排序上进行改进得到的,一个长度为 n 的数组,下标 n-1 出是最小值,该值移动到下标 0 处,
115 * 普通的插入排序需要比较 n-1 次,
116 * 希尔排序在进行最后一次排序前,会将这个值先排到前列,使得其比较移动的次数变少了。
117 *
118 * @param arr 排序数组
119 */
120 private static void shellSort(int[] arr) {
121 for (int d = arr.length / 2; d > 0; d /= 2) {
122 for (int i = d; i < arr.length; i += d) { //此处如果d为1 ,那么就类似一个插入排序算法
123 for (int j = i; j > 0; j -= d) {
124 if (arr[j - d] > arr[j]) {
125 int temp = arr[j - d];
126 arr[j - d] = arr[j];
127 arr[j] = temp;
128 } else {
129 break;
130 }
131 }
132 }
133 }
134 }
135
136
137 /**
138 * 插入排序,思想是从数组中选取一个下标位置,我们认为这个位置之前的数据全部是正序的,
139 * 我们只需要将这个位置的元素与前面的序列进行比较,将其插入到合适的位置即可
140 * 因为前面是正序的,那么从插入位置开始(包含插入位置)的元素依次向后挪动一个位置。
141 * 为了保证前面的元素都是正序的,我们从下标1开始进行比较
142 *
143 * @param arr 排序的数组
144 */
145 private static void insertSort(int[] arr) {
146 for (int i = 1; i < arr.length; i++) { //0下标位置的元素不用选取比较
147 for (int j = i; j > 0; j--) {
148 if (arr[j - 1] > arr[j]) { //此处还可以不用每次交换,使用两个变量记录被选择位置的值和最后比较到的位置,每次将值向后挪动一次,最后将值插入最后比较位置
149 int temp = arr[j];
150 arr[j] = arr[j - 1];
151 arr[j - 1] = temp;
152 } else {
153 break;
154 }
155 }
156 }
157 }
158
159
160 /**
161 * 快速排序,
162 * 每次取一个中间值,将数组中的元素分隔成大于中间值的一部分,和小于中间值的一部分。
163 * 之后对上述两个部分重复该过程,直到每个部分的元素个数不能再细分为止。
164 * 综上所述,使用递归方法方法实现最为有效
165 *
166 * @param arr 数组
167 * @param start 本次需要进行比较部分的起始下标
168 * @param end 本次需要进行比较部分的结束下标
169 */
170 private static void quickylySort(int[] arr, int start, int end) {
171 if (start < end) { //保证要被比较的数组段落确实存在,也保证递归不会无限制执行
172 int i = start;
173 int j = end;
174 int tag = arr[i];
175 while (i < j) {
176 while (i < j && arr[j] >= tag) {
177 j--;
178 }
179 if (i < j) {
180 arr[i] = arr[j];
181 }
182
183 while (i < j && arr[i] <= tag) {
184 i++;
185 }
186 if (i < j) {
187 arr[j] = arr[i];
188 }
189 }
190 arr[i] = tag;
191 quickylySort(arr, start, i - 1);
192 quickylySort(arr, i + 1, end);
193 }
194 }
195
196
197 /**
198 * 冒泡排序,以结果为正序排序为准:
199 * 每次比较两个相邻的元素,将较大的置于后面位置,
200 * 这样每一次对数组进行遍历比较过后都能得到一个最后位置的最大值。
201 * 之后每一次遍历比较,上述最大值不再参与比较。
202 *
203 * @param arr 数组
204 */
205 private static void bubbSort(int[] arr) {
206 for (int i = 0; i < arr.length - 1; i++) {
207 for (int j = 0; j < arr.length - 1 - i; j++) {
208 if (arr[j] > arr[j + 1]) {
209 int temp = arr[j];
210 arr[j] = arr[j + 1];
211 arr[j + 1] = temp;
212 }
213 }
214 }
215 }
216
217
218 }