各种排序算法

  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 }
排序代码
原文地址:https://www.cnblogs.com/soficircle/p/11800896.html