排序算法
常用的八种排序算法:冒泡排序、选择排序、插入排序、快速排序、归并排序、基数排序、希尔排序、堆排序
github: https://github.com/Allin1579/Java
/** * Main * @author Allin */ public class Main { public static void main(String[] args) { //创建无序数组 int[] s = Factory.createArray(100000); //排序 long start = System.currentTimeMillis(); Sort.sort(s); long end = System.currentTimeMillis(); System.out.println(String.format("排序耗时%sms", String.valueOf(end - start))); //检查排序是否正确 Sort.isOrder(s); } }
/** * 数据工厂 * @author Allin */ public class Factory { /** * 创建长度为length的int数组 * @param length * @return int[] */ public static int[] createArray(int length){ int[] s = new int[length]; for (int i = 0; i < length; i++) { s[i] = createInt(); } return s; } /** * 创建0到100的随机数,强转为int * @return int */ private static int createInt(){ int i = (int) (Math.random() * 100); return i; } }
/** * 排序算法 * @author Allin */ public class Sort { public static void sort(int[] s){ //算法选择 bubbleSort(s); // selectSort(s); // insertSort(s); // quickSort(s, 0, s.length - 1); // mergerSort(s, 0, s.length - 1); // radixSort(s, 3); // shellSort(s); // heapSort(s); } /** * 冒泡排序 * @param s * @return */ public static void bubbleSort(int[] s){ if(s == null || s.length <= 0){ return; } for(int i = 0; i < s.length; i++){ for(int j = 0; j < s.length - i - 1; j++){ if(s[j] > s[j + 1]){ int temp = s[j]; s[j] = s[j + 1]; s[j + 1] = temp; } } } } /** * 选择排序 * @param s * @return */ public static void selectSort(int[] s){ if(s == null || s.length <= 0){ return; } for(int i = 0; i < s.length - 1; i++){ //O = n + (n + 1) + (n + 2) + ... + 1 = O(n^2) for(int j = i + 1; j< s.length; j++){ if(s[i] > s[j]){ int temp = s[i]; s[i] = s[j]; s[j] = temp; } } } } /** * 插入排序 * @param s * @return */ public static void insertSort(int[] s){ if(s == null || s.length <= 0){ return; } for (int i = 1; i < s.length; i++){ if (s[i - 1] > s[i]) { int temp = s[i]; int j = i; while (j > 0 && s[j - 1] > temp){ s[j] = s[j - 1];//往后挪 j--; } s[j] = temp; } } } /** * 快速排序 * @param s * @return */ public static void quickSort(int[] s, int l, int r){ if(s == null || s.length <= 0){ return; } if (l < r) { int i = l, j = r, x = s[l]; //取第一个元素为基准 while (i < j) { while(i < j && s[j] >= x) // 从右向左找第一个小于x的数 j--; if(i < j) s[i++] = s[j]; while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数 i++; if(i < j) s[j--] = s[i]; } s[i] = x; //i==j quickSort(s, l, i - 1); // 递归调用 quickSort(s, i + 1, r); } } /** * 归并排序 * @param s * @return */ public static void mergerSort(int[] s, int l, int r){ if(s == null || s.length <= 0){ return; } if (l < r) { int mid = (l + r) / 2; //左边 mergerSort(s, l, mid); //右边 mergerSort(s, mid + 1, r); //左右归并 merger(s, l, mid, r); } } /** * 归并 * @param s * @param l * @param mid * @param r */ private static void merger(int[] s, int l, int mid, int r){ int[] temp = new int[r - l + 1]; int i = l;// 左指针 int j = mid + 1;// 右指针 int k = 0; // 把较小的数先移到新数组中 while (i <= mid && j <= r) { if (s[i] < s[j]) { temp[k++] = s[i++]; } else { temp[k++] = s[j++]; } } // 把左边剩余的数移入数组 while (i <= mid) { temp[k++] = s[i++]; } // 把右边边剩余的数移入数组 while (j <= r) { temp[k++] = s[j++]; } // 把新数组中的数覆盖s数组 for (int q = 0; q < temp.length; q++) { s[q + l] = temp[q]; } } /** * 基数排序 * @param s * @return */ public static void radixSort(int[] s, int digit){ if(s == null || s.length <= 0){ return; } final int l = 0; final int r = s.length -1; final int radix = 10; // 基数 int i = 0, j = 0; int[] count = new int[radix]; // 存放各个桶的数据统计个数 int[] bucket = new int[r - l + 1]; // 按照从低位到高位的顺序执行排序过程 for (int d = 1; d <= digit; d++) { // 置空各个桶的数据统计 for (i = 0; i < radix; i++) { count[i] = 0; } // 统计各个桶将要装入的数据个数 for (i = l; i <= r; i++) { j = getDigit(s[i], d); count[j]++; } // count[i]表示第i个桶的右边界索引 for (i = 1; i < radix; i++) { count[i] = count[i] + count[i - 1]; } // 将数据依次装入桶中 // 这里要从右向左扫描,保证排序稳定性 for (i = r; i >= l; i--) { j = getDigit(s[i], d); // 求出关键码的第k位的数字, 例如:576的第3位是5 bucket[count[j] - 1] = s[i]; //放入对应的桶中,count[j]-1是第j个桶的右边界索引 count[j]--; // 对应桶的装入数据索引减一 } // 将已分配好的桶中数据再倒出来,此时已是对应当前位数有序的表 for (i = l, j = 0; i <= r; i++, j++) { s[i] = bucket[j]; } } } /** * getDigit * @param x * @param d * @return */ private static int getDigit(int x, int d) { int a[] = { 1, 1, 10, 100 }; // 本实例中的最大数是百位数,所以只要到100就可以了 return ((x / a[d]) % 10); } /** * 希尔排序 * @param s * @return */ public static void shellSort(int[] s){ if(s == null || s.length <= 0){ return; } int len = s.length; int group, i, j, temp; for (group = len / 2; group > 0; group /= 2) { for (i = group; i < len; i++) { for (j = i - group; j >= 0; j -= group) { if (s[j] > s[j + group]) { temp = s[j]; s[j] = s[j + group]; s[j + group] = temp; } } } } } /** * 堆排序 * @param s * @return */ public static void heapSort(int[] s){ if(s == null || s.length <= 0){ return; } } /** * 检查排序是否正确 * @param s * @return */ public static boolean isOrder(int[] s){ for(int i = 0; i< s.length - 1; i++){ if(s[i] > s[i+1]){ System.out.println("排序失败"); return false; } } System.out.println("排序成功"); return true; } }