package edu.cn.ysw; //八种排序算法的实现与效率分析 /* * 内排序的种类: * 1.插入排序:直接插入排序、希尔排序。 * 2.选择排序:简单选择排序、堆排序。 3.交换排序:冒泡排序、快速排序。 4.归并排序 5.基数排序 */ public class SortedMethods { /** * @author ysw * @param args * @throws Exception * @since 6/15/2017 */ // 直接插入排序:1.有哨兵;2.无哨兵 // 无哨兵 public void insertSortWithoutPre(int arr[]) { if (arr == null || arr.length == 0) { return; } // 外层循环定义排序次数 for (int i = 1; i < arr.length; i++) { // 不满足条件则忽略此次判断,相当于continue; if (arr[i] < arr[i - 1]) { int tempValue = arr[i]; int j; for (j = i - 1; j >= 0 && tempValue < arr[j]; j--) { arr[j + 1] = arr[j]; } arr[j + 1] = tempValue; } } } // 有哨兵的直接插入排序 public void insertSortWithPre(int arr[]) { for (int i = 2; i < arr.length; i++) { /* * 哨兵的作用: 1:保存等待插入的数字; 2:防止数组越界的情况; */ if (arr[i] < arr[i - 1]) { arr[0] = arr[i]; int j; for (j = i - 1; arr[0] < arr[j]; j--) { arr[j + 1] = arr[j]; } arr[j + 1] = arr[0]; } } } // 希尔排序 public void shellSort(int arr[]) { if (arr == null || arr.length == 0) { return; } // 增量序列 int incrementValue = arr.length / 2; while (incrementValue >= 1) { for (int i = 0; i < arr.length; i++) { for (int j = i + incrementValue; j < arr.length; j += incrementValue) { int temp = arr[j]; int k; for (k = j - incrementValue; k >= 0 && arr[k] > temp; k = k - incrementValue) { arr[k + incrementValue] = arr[k]; } arr[k + incrementValue] = temp; } } // 改变递增序列的值 incrementValue /= 2; } } /* * 选择排序: 1.简单选择排序 2.堆排序 */ // 简单选择排序 public void selectSort(int arr[]) { for (int i = 0; i < arr.length - 1; i++) { for (int j = i + 1; j < arr.length; j++) { if (arr[i] > arr[j]) { swap(arr, i, j); } } } } // 堆排序:实践中多用于调度算法,比如线程优先级调度 // 时间驱动:取最小值或者等待时间最长 // 冒泡排序 public void bubbleSort(int arr[]) { for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { swap(arr, j, j + 1); } } } } // 快速排序:挖坑填数+分治 // 快速排序返回基准值最终位置的函数partition:回调整后基准数的位置 public int partition(int arr[], int l, int r) { // 假设第一个基准值为arr[0]; int left = l; int right = r; int key = arr[left]; while (left < right) { while (left < right && arr[right] >= key) { right--; } if (left < right) { arr[left] = arr[right]; left++; } while (left < right && arr[left] <= key) { left++; } if (left < right) { arr[right] = arr[left]; right--; } } arr[left] = key; return left; } // 快速排序 public void quickSort(int arr[], int l, int r) { if (l < r) { int index = partition(arr, l, r); quickSort(arr, l, index - 1); quickSort(arr, index + 1, r); } } // 归并排序 public void mergeSort(int arr[]) { sort(arr, 0, arr.length - 1); } public void sort(int[] arr, int left, int right) { if (left >= right) { return; } int center = (left + right) / 2; sort(arr, left, center); sort(arr, center + 1, right); merge(arr, left, center, right); } public void merge(int[] arr, int left, int center, int right) { // 定义一个辅助数组来存放归并的两个子数组 int tempArray[] = new int[arr.length]; // 左面子数组的第一个元素 int leftFirst = left; // 右面子数组的第一个元素 int rightFirst = center + 1; // 指向辅助数组的第一个元素 int tempPointer = left; while (leftFirst <= center && rightFirst <= right) { if (arr[leftFirst] <= arr[rightFirst]) { tempArray[tempPointer++] = arr[leftFirst++]; } else { tempArray[tempPointer++] = arr[rightFirst++]; } } // 将第一个数组中剩下的元素添加到辅助数组中 while (leftFirst <= center) { tempArray[tempPointer++] = arr[leftFirst++]; } // 将第二个数组中剩下的元素添加到辅助数组中 while (rightFirst <= right) { tempArray[tempPointer++] = arr[rightFirst++]; } } // 打印数组的函数 public void printArr(int arr[]) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]); if (i != arr.length - 1) { System.out.print(","); } } System.out.println(); } // 交换数组的元素 public void swap(int arr[], int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } public static void main(String[] args) { SortedMethods sMethods = new SortedMethods(); // 测试需要的数组 int array1[] = { 1, 2, 3, 4, 5 }; int array2[] = { 5, 4, 3, 2, 1 }; int array3[] = { 4, 5, 2, 1, 7 }; int array4[] = null; int array5[] = new int[0]; // 测试无哨兵的插入排序 System.out.println("--------有哨兵插入排序--------------"); sMethods.insertSortWithoutPre(array1); sMethods.printArr(array1); sMethods.insertSortWithoutPre(array2); sMethods.printArr(array2); sMethods.insertSortWithoutPre(array3); sMethods.printArr(array3); /* * sMethods.insertSortWithoutPre(array4); sMethods.printArr(array4); * sMethods.insertSortWithoutPre(array5); sMethods.printArr(array5); */ System.out.println("--------无哨兵插入排序------------"); // 测试有哨兵的插入排序 sMethods.insertSortWithoutPre(array1); sMethods.printArr(array1); sMethods.insertSortWithoutPre(array2); sMethods.printArr(array2); sMethods.insertSortWithoutPre(array3); sMethods.printArr(array3); System.out.println("----------希尔排序------------"); // 测试希尔排序 sMethods.shellSort(array1); sMethods.printArr(array1); sMethods.shellSort(array2); sMethods.printArr(array2); sMethods.shellSort(array3); sMethods.printArr(array3); System.out.println("---------简单选择排序------------"); sMethods.selectSort(array1); sMethods.printArr(array1); sMethods.selectSort(array2); sMethods.printArr(array2); sMethods.selectSort(array3); sMethods.printArr(array3); System.out.println("---------冒泡排序------------"); sMethods.bubbleSort(array1); sMethods.printArr(array1); sMethods.bubbleSort(array2); sMethods.printArr(array2); sMethods.bubbleSort(array3); sMethods.printArr(array3); System.out.println("---------快速排序------------"); sMethods.quickSort(array3, 0, array3.length - 1); sMethods.printArr(array3); System.out.println("---------归并排序排序------------"); sMethods.mergeSort(array3); sMethods.printArr(array3); } }