常用排序算法(Java描述)
代码如下:
package cn.ganlixin.sort; import lombok.AllArgsConstructor; import lombok.Data; import org.junit.Test; import java.util.Objects; public class SortTest { @Test public void testBubbleSort() { Person[] arr = new Person[4]; arr[0] = new Person(5, "abc"); arr[1] = new Person(3, "xyz"); arr[2] = new Person(7, "qaq"); arr[3] = new Person(1, "lol"); // bubbleSort(arr); // selectSort(arr); // insertSort(arr); // int[] gapList = {7, 5, 3, 1}; // shellSort(arr, gapList); // quickSort(arr, 0, arr.length - 1); mergeSort(arr, 0, arr.length - 1, new Comparable[4]); printArray(arr); } @Data @AllArgsConstructor private static class Person implements Comparable<Person> { // 注意,对象之间如果需要进行比较,则必须实现Comparable接口,并重写compareTo方法 private Integer id; private String name; @Override public int compareTo(Person otherPerson) { if (Objects.isNull(this.id) || Objects.isNull(otherPerson) || Objects.isNull(otherPerson.getId())) { return -1; } return this.id.compareTo(otherPerson.getId()); } } /** * 工具方法,用于打印数组 */ private void printArray(Comparable[] arr) { if (Objects.isNull(arr) || arr.length == 0) { return; } for (Comparable comparable : arr) { System.out.println(comparable); } } /** * 冒泡排序(排序后,id从小到大) * * @param arr 待排序的对象数组 */ public void bubbleSort(Comparable[] arr) { if (Objects.isNull(arr) || arr.length == 0) { return; } int length = arr.length; for (int i = 0; i < length; i++) { for (int j = i + 1; j < length; j++) { if (arr[i].compareTo(arr[j]) > 0) { Comparable tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } } } /** * 选择排序(排序后,id从小到大) * * @param arr 待排序数组 */ public void selectSort(Comparable[] arr) { if (Objects.isNull(arr) || arr.length == 0) { return; } int length = arr.length; for (int i = 0; i < length; i++) { int min = i; // min记录本轮最小值的下标 for (int j = i + 1; j < length; j++) { if (arr[min].compareTo(arr[j]) > 0) { min = j; // 发现更小的元素,则将min改为更小元素的下标 } } if (i != min) { Comparable tmp = arr[i]; arr[i] = arr[min]; arr[min] = tmp; } } } /** * 插入排序(排序后,id从小到大) * * @param arr 待排序数组 */ public void insertSort(Comparable[] arr) { if (Objects.isNull(arr) || arr.length == 0) { return; } int length = arr.length; for (int i = 1; i < length; i++) { // 当前所指向的元素比他前面一个元素要小,需调整次序 if (arr[i].compareTo(arr[i - 1]) < 0) { Comparable tmp = arr[i]; // 记录要插入的元素 int j; // j指向当前元素应该插入的位置 // 从i往前倒推,找到tmp应该插入的位置(不断将前面比tmp大的元素往后移) for (j = i; j > 0 && tmp.compareTo(arr[j - 1]) < 0; j--) { arr[j] = arr[j - 1]; } arr[j] = tmp; } } } /** * 希尔排序(排序后,id从小到大) * * @param arr 待排序的数组 * @param gapList 希尔排序每轮插入排序的增量(小于n的数) */ public void shellSort(Comparable[] arr, int[] gapList) { if (Objects.isNull(arr) || arr.length == 0) { return; } if (Objects.isNull(gapList) || gapList.length == 0) { // 没有指定增量时,希尔排序就是插入排序,调用前面的插入排序即可 insertSort(arr); return; } // 指定了增量,插入排序的变形 int gapNum = gapList.length; int arrLength = arr.length; for (int i = 0; i < gapNum; i++) { int gap = gapList[i]; // 获取本轮的增量 for (int j = gap; j < arrLength; j++) { if (arr[j].compareTo(arr[j - gap]) < 0) { Comparable tmp = arr[j]; int k; for (k = j; k > 0 && tmp.compareTo(arr[k - 1]) < 0; k -= gap) { arr[k] = arr[k - gap]; } arr[k] = tmp; } } } } /** * 快速排序(排序后,id从小到大) * * @param arr 待排序数组 * @param low 需要排序的区间低位(排序在low ~ hight进行,index从0开始) * @param high 需要排序的区间高位(排序在low ~ hight进行, index从0开始) */ public void quickSort(Comparable[] arr, int low, int high) { if (Objects.isNull(arr) || arr.length == 0 || high <= low) { return; } Comparable tmp = arr[low];// tmp表示本次比较的枢纽元素 while (low < high) { // 从右向左搜索比枢纽元素要小的元素 while (low < high && arr[high].compareTo(tmp) >= 0) { --high; } // 在枢纽元素的右边遇到了比枢纽元素要小的元素,则进行交换(即使low和high指向一处) arr[low] = arr[high]; // 从左向有搜索比枢纽元素要大的元素 while (low < high && arr[low].compareTo(tmp) <= 0) { ++low; } // 在枢纽元素的左边遇到了比枢纽元素要大的元素,则进行交换(即使low和high指向一处) arr[high] = arr[low]; } // 将枢纽元素放入(此时low和high相同) arr[low] = tmp; // 递归分别排序左右两部分 quickSort(arr, 0, low); quickSort(arr, low + 1, high); } /** * 归并排序(排序的最终结果在result数组中) * * @param arr 待排序的数组 * @param start 待排序部分的低位下标 * @param end 待排序不分的高位下标 * @param helpArr 辅助数组 */ public void mergeSort(Comparable[] arr, int start, int end, Comparable[] helpArr) { if (Objects.isNull(arr) || arr.length == 0 || end <= start) { return; } int mid = (start + end) / 2; // 排序左边部分 int start1 = start; int end1 = mid; mergeSort(arr, start1, end1, helpArr); // 排序右边部分 int start2 = mid + 1; int end2 = end; mergeSort(arr, start2, end2, helpArr); // 合并左右两部分 int mergeIndex = start; while (start1 <= end1 && start2 <= end2) { if (arr[start1].compareTo(arr[start2]) <= 0) { helpArr[mergeIndex++] = arr[start1++]; } else { helpArr[mergeIndex++] = arr[start2++]; } } while (start1 <= end1) { helpArr[mergeIndex++] = arr[start1++]; } while (start2 <= end2) { helpArr[mergeIndex++] = arr[start2++]; } // 将辅助数组中的元素拷贝到原数组中 for (int i = start; i <= end; i++) { arr[i] = helpArr[i]; } } }
如需转载,请注明文章出处,谢谢!!!