提供了以下排序:冒泡排序
选择排序
插入排序
希尔排序
快速排序
归并排序
桶排序
堆排序
package com.xingej.algorithm.sort;import java.util.ArrayList;import java.util.Collections;/** * 排序工具类 * * @author erjun 2017年12月13日 上午8:38:22 */public class SortUtils { // 私有构造器,禁止外界创建对象 private SortUtils() { } // --------1、冒泡排序------ /** * * 冒泡排序核心:1、从数组的最后一个元素,开始比较;2、两两比较,满足条件的话,就需要进行位置的互换 * * 实际生活中:小学时,需要根据身高进行座位排序,就可以使用冒泡排序进行。 * */ public static void bubbleSort(int[] arr) { int temp; // 4 3 2 1,按冒泡排序的话,需要进行3轮比较可以了 for (int i = 0; i i; j--) { // 后面的/下面的水泡 小于 上面的水泡,就移位 if (arr[j] b,那么minIndex就是b的下标 int value; for (int i = 0; i arr[j]) { minIndex = j;// 将最小下标赋值给minIndex } } // 将最小值与第一个元素,进行交换 arr[i] = arr[minIndex]; arr[minIndex] = value; } } // --------3、插入排序------ /** * 插入排序,的思想跟冒泡排序和选择排序不同 * * 使用场景很像打牌时,每抓到一个张牌,按照大小插入到"已经排序好"的牌里 * * 实际应用场景:有排序好的元素,还有一些未排序的元素,这个时候可以考虑插入排序 * * 其实,将待排序的元素,插入到已经排序好的元素时, * * 可以使用别的排序方法,来进行,不必循序查询比较排序,可以使用快速排序 * * @param arr */ public static void insertSort(int[] arr) { // right表示,未排序的元素 for (int right = 1; right = 0 && arr[left] > temp) { arr[left + 1] = arr[left]; left--; } // 为什么left+1呢? // 因为,上面的while循环中,left 减 1 之后, 不满足循环条件的, // 因此,需要将temp值放到left+1的位置上去 arr[left + 1] = temp; } } // --------4、希尔排序------ public static void shellSort(int[] arr) { int left; // 左边下标,表示,已经排序好的元素 int right; // 右边下标,表示,待排序元素/就是没有排序的元素 int temp; // 临时存储 int h = 1; // 初始间隔为1; // 计算最大间隔 while (h 0) { // 表示循环待排序的元素 for (right = h; right h-1, // 目前我认为是,保证arr[left-h] 得有值,不能为空,或者说,报空指针异常吧 while (left > h - 1 && arr[left - h] >= temp) { arr[left] = arr[left - h]; left = left - h; } // 这里,千万不要写成下面的形式, 不能再left-h,因为,上面的while()循环,已经减去了 // arr[left - h] = temp; arr[left] = temp; } // 重新调整排序间隔 h = (h - 1) / 3; } } // --------5、快速排序------ public static void quickSort(int arr[]) { recQuickSort(arr, 0, arr.length - 1); } // 使用递归和划分技术进行快速排序 private static void recQuickSort(int arr[], int left, int right) { int size = right - left + 1; if (size pivot) ; if (leftPtr >= rightPtr) { break; // 结束时,leftPtr = rightPtr } else { swap(arr, leftPtr, rightPtr); // 交换 } } swap(arr, leftPtr, right - 1); return leftPtr; } // 找出中间值 // 索引为left,right,以及中间值的 进行排序, private static int medianof3(int arr[], int left, int right) { int centerIndex = (left + right) / 2; if (arr[left] > arr[centerIndex]) { swap(arr, left, centerIndex); } if (arr[left] > arr[right]) { swap(arr, left, right); } if (arr[centerIndex] > arr[right]) { swap(arr, centerIndex, right); } swap(arr, centerIndex, right - 1); return arr[right - 1]; } private static void insertSort(int arr[], int left, int right) { int in, out; int temp; // 临时缓存,待存储的元素 for (out = left + 1; out <= right; out++) { temp = arr[out]; in = out; while (in > left && arr[in - 1] >= temp) { arr[in] = arr[in - 1]; in--; } arr[in] = temp; } } private static void swap(int arr[], int left, int right) { int temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; } // --------6、归并排序------ // 归并两个已经有序的数组 // 首先将数组,拆分成两部分,左边做成有序的,同样,右边也做成有序的。 // 将这两个有序的数组,组合生成第3个有序的数组, // 时间复杂度O(N*logN) // 缺点:消耗内存; public static void mergeSort(int arr[]) { // 生成临时的缓存数组,用于临时排序 int[] workSpace = new int[arr.length]; recMergeSort(arr, workSpace, 0, arr.length - 1); } // lowerBound,upperBound 全是数组下标 private static void recMergeSort(int arr[], int workSpace[], int lowerBound, int upperBound) { if (lowerBound == upperBound) { return; } else { int mid = (lowerBound + upperBound) / 2; // 递归前半部分 recMergeSort(arr, workSpace, lowerBound, mid); // 递归后半部分 recMergeSort(arr, workSpace, mid + 1, upperBound); // 进行合并 merge(arr, workSpace, lowerBound, mid + 1, upperBound); } } /** * * @param arr * 被排序的数组 * @param workSpace * 临时缓存,进行排序的 * @param lowPtr * 前半部分,最小下标 * @param highPtr * 后半部分,最小下标 * @param upperBound * 后半部分,最大下标 */ private static void merge(int arr[], int workSpace[], int lowPtr, int highPtr, int upperBound) { int i = 0; int lowerBound = lowPtr;// 前半部分的最小下标,进行缓存 int mid = highPtr - 1; int n = upperBound - lowerBound + 1; while (lowPtr <= mid && highPtr <= upperBound) { if (arr[lowPtr] > bucketArr = new ArrayList<>(); for (int i = 0; i ()); } // 遍历数组,将每个元素放入桶中 for (int i = 0; i arrayList = bucketArr.get(i); for (Integer key : arrayList) { arr[j++] = key; } } } // --------8、堆排序------ // 堆特点: // 1、它是完全的二叉树,除了树的最后一层节点不需要是满的,其他的每一层从左到右都完全是满的 // 2、它常常是用一个数组来实现堆的 // 3、堆中的每一个节点都满足的条件是,父节点的关键字要大于所有的子节点 public static void heapSort(int arr[]) { int size = arr.length; Heap heap = new Heap(size); for (int i = 0; i = 0; j--) { heap.trickleDown(j); } // 通过循环删除最大项,再把删除的数据,数组中的指定的位置,如从后往前方; // 结果就是从小到大排序 for (int j = size - 1; j >= 0; j--) { Node biggestNode = heap.remove();// 取出最大的数据项 heap.insertAt(j, biggestNode); } System.out.println("----打印排序后的堆----"); heap.displayArray(); } // 堆排序, // 堆是二叉树,因此,需要创建这个节点,来存储数据 // 堆的特点:父节点的值要大于子节点,左右子节点大小无关系,不要求左子节点小于右子节点 static class Node { private int iData; public Node(int key) { iData = key; } public int getKey() { return iData; } public void setKey(int id) { iData = id; } } // 创建堆 static class Heap { private Node[] heapArray; private int maxSize; private int currentSize; public Heap(int mx) { maxSize = mx; currentSize = 0; heapArray = new Node[maxSize]; } public boolean isEmpty() { return currentSize == 0; } // 插入指定的位置 public void insertAt(int index, Node node) { heapArray[index] = node; } public void incrementSize() { currentSize++; } public Node remove() { Node root = heapArray[0]; heapArray[0] = heapArray[--currentSize];// 把最后一个元素,赋值到根元素上 trickleDown(0);// 开始向下调整 return root; } // 向下调整 public void trickleDown(int index) { int largerChild; Node top = heapArray[index]; while (index = heapArray[largerChild].getKey()) { break; } heapArray[index] = heapArray[largerChild]; index = largerChild; } heapArray[index] = top; } // 树状的方式,显示堆 public void displayHeap() { int nBlanks = 32; int itemsPerRow = 1;// 层数判断 int column = 0; int j = 0; String dots = "-------------------------"; System.out.println(dots + dots); while (currentSize > 0) { if (column == 0) { for (int k = 0; k
测试用例:package com.xingej.algorithm.sort;import org.junit.Before;import org.junit.Test;public class SortTest { private int max = 20; private int[] arr = new int[max]; // 初始化数组 @Before public void initArray() { for (int i = 0; i