文章标题
来源:互联网 发布:win 10 网络初始化失败 编辑:程序博客网 时间:2024/06/07 01:26
7种基本排序算法的Java实现
转自我的Github
以下为7种基本排序算法的Java实现,以及复杂度和稳定性的相关信息。
以下为代码片段,完整的代码见Sort.java
插入排序
/** * 直接插入排序 * 不稳定 * 时间复杂度:O(n^2) * 最差时间复杂度:O(n^2) * 空间复杂度:O(1) * 使用场景:大部分元素有序 * @param elements * @param comparator * @param <T> */ public <T> void insertSort(T[] elements, Comparator<T> comparator) { if (isInputInvalid(elements, comparator)) { return; } int length = elements.length; for (int i = 1; i < length; i++) { T current = elements[i]; int j; for (j = i; j > 0; j--) { if (comparator.compare(elements[j - 1], current) > 0) { elements[j] = elements[j - 1]; } else { break; } } elements[j] = current; } }
Shell排序
/** * 希尔排序 * 不稳定 * 时间复杂度:O(nlogn) * 最差时间复杂度:O(n^s) 1<s<2 * 空间复杂度:O(1) * 使用场景:元素小于5000 * @param elements * @param comparator * @param <T> */ public <T> void shellSort(T[] elements, Comparator<T> comparator) { if (isInputInvalid(elements, comparator)) { return; } int length = elements.length; for (int gap = length/2; gap >= 1; gap /= 2) { for (int i = gap; i < length; i++) { T current = elements[i]; int j; for (j = i; j >= gap; j = j - gap) { if (comparator.compare(elements[j - gap], current) > 0) { elements[j] = elements[j - gap]; } else { break; } } elements[j] = current; }// printArray(elements, "gap:" + gap); } }
选择排序
/** * 选择排序 * 稳定 * 时间复杂度:O(n^2) * 最差时间复杂度:O(n^2) * 空间复杂度:O(1) * 使用场景:n较少时 * @param elements * @param comparator * @param <T> */ public <T> void selectSort(T[] elements, Comparator<T> comparator) { if (isInputInvalid(elements, comparator)) { return; } int length = elements.length; for (int i = 0; i < length - 1; i++) { int min = i; for (int j = i + 1; j < length; j++) { if (comparator.compare(elements[min], elements[j]) > 0) { min = j; } } if (min != i) { swap(elements, min, i); } } }
堆排序
优先级队列内部实现就是一个最小堆,这里就不自己实现heap了
/** * 堆排序 * 时间复杂度:O(nlogn) * 最差时间复杂度:O(nlogn) * 空间复杂度:O(n) * 使用场景:n较大时 * @param elements * @param comparator * @param <T> */ public <T> void heapSort(T[] elements, Comparator<T> comparator) { if (isInputInvalid(elements, comparator)) { return; } PriorityQueue<T> heap = new PriorityQueue(elements.length, comparator); for (T element : elements) { heap.add(element); } for (int i = 0; i < elements.length; i++) { elements[i] = heap.poll(); } }
冒泡排序
/** * 冒泡排序 * 稳定 * 时间复杂度:O(n^2) * 空间复杂度:O(1) * 使用场景:n较小时 * @param elements * @param comparator * @param <T> */ public <T> void bubbleSort(T[] elements, Comparator<T> comparator) { if (isInputInvalid(elements, comparator)) { return; } int length = elements.length; for (int i = 1; i < length; i++) { for (int j = length - 1; j >= i; j--) { if (comparator.compare(elements[j - 1], elements[j]) > 0) { swap(elements, j - 1, j); } } } }
快排
/** * 快速排序 * 不稳定 * 时间复杂度:O(nlogn) * 最差时间复杂度:O(n^2) * 空间复杂度:O(logn) * 使用场景:由于是递归,不适合内存有限制的情况, n较大时 * @param elements * @param comparator * @param <T> */ public <T> void quickSort(T[] elements, Comparator<T> comparator) { if (isInputInvalid(elements, comparator)) { return; } doQuickSort(elements, 0, elements.length - 1, comparator); } private <T> void doQuickSort(T[] elements, int start, int end, Comparator<T> comparator) { if (start >= end) { return; } int pivot = partition(elements, start, end, comparator); doQuickSort(elements, start, pivot - 1, comparator); doQuickSort(elements, pivot + 1, end, comparator); } private <T> int partition(T[] elements, int start, int end, Comparator<T> comparator) { T pivot = elements[start]; int pivotIndex = start, forward = start, back = end; while (forward < back) { for (; comparator.compare(pivot, elements[forward]) >= 0 && forward < end; forward++) {} for (; comparator.compare(pivot, elements[back]) <= 0 && back > start; back--) {} if (forward < back) { swap(elements, forward++, back--); } } swap(elements, back, pivotIndex); return back; }
归并排序
/** * 归并排序 * 不稳定 * 时间复杂度:O(nlogn) * 最差时间复杂度:O(nlogn) * 空间复杂度:O(n) * 使用场景:n较大时 * @param elements * @param comparator * @param <T> */ public <T> void mergeSort(T[] elements, Comparator<T> comparator) { if (isInputInvalid(elements, comparator)) { return; } Object[] aux = new Object[elements.length]; int start = 0, end = elements.length - 1; doMergeSort(elements, start, end, comparator, aux); } private <T> void doMergeSort(T[] elements, int start, int end, Comparator<T> comparator, Object[] aux) { if (start >= end) { return; } int mid = (start + end) / 2; doMergeSort(elements, start, mid, comparator, aux); doMergeSort(elements, mid + 1, end, comparator, aux); merge(elements, start, mid, end, comparator, aux); } private <T> void merge(T[] elements, int start, int mid, int end, Comparator<T> comparator, Object[] aux) { int lb = start, rb = mid + 1, auxIndex = start; while (lb <= mid && rb <= end) { if (comparator.compare(elements[lb], elements[rb]) <= 0) { aux[auxIndex++] = elements[lb++]; } else { aux[auxIndex++] = elements[rb++]; } } if (lb < mid + 1) { while(lb <= mid) { aux[auxIndex++] = elements[lb++]; } } else { while(rb <= end) { aux[auxIndex++] = elements[rb++]; } } for(int i = start; i <= end; i++) { elements[i] = (T) aux[i]; } }
测试用方法
public static void main(String[] args) { Integer[] elements = {3, 543, 54, 5, 6, 2, 67, 3, 65, 4};// Integer[] elements = {0,0,0,0,0,0,0,0,0,0,0}; printArray(elements, "OriginalArray"); Sort sort = new Sort(); Integer[] dupArray = dupArray(elements); sort.bubbleSort(dupArray, (o1, o2) -> o1 - o2); printArray(dupArray, "BubbleSort"); dupArray = dupArray(elements); sort.insertSort(dupArray, (o1, o2) -> o1 - o2); printArray(dupArray, "InsertSort"); dupArray = dupArray(elements); sort.selectSort(dupArray, (o1, o2) -> o1 - o2); printArray(dupArray, "SelectSort"); dupArray = dupArray(elements); sort.heapSort(dupArray, (o1, o2) -> o1 - o2); printArray(dupArray, "HeapSort"); dupArray = dupArray(elements); sort.quickSort(dupArray, (o1, o2) -> o1 - o2); printArray(dupArray, "QuickSort"); dupArray = dupArray(elements); sort.shellSort(dupArray, (o1, o2) -> o1 - o2); printArray(dupArray, "ShellSort"); dupArray = dupArray(elements); sort.mergeSort(dupArray, (o1, o2) -> o1 - o2); printArray(dupArray, "MergeSort"); } private static <T> T[] dupArray(T[] array) { return Arrays.copyOf(array, array.length); } private static <T> void printArray(T[] array, String des) { System.out.println(arrayToString(array) + " :" + des); } public static <T> String arrayToString(T[] array) { StringBuilder resultBuilder = new StringBuilder(); resultBuilder.append("{"); for (T item : array) { resultBuilder.append(item).append(","); } resultBuilder.deleteCharAt(resultBuilder.length() - 1); resultBuilder.append("}"); return resultBuilder.toString(); }
当然每种算法根据自身的缺陷都有可以改进的地方,可以结合不同的情况使用不同的排序算法,比如快排中使用三者取中的pivot选取方法,或者在快排在递归到比较小的元素划分的时候使用插入排序等等。
文中有不足之处还请大家批评指正。
0 0
- 文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题 文章标题 文章标题 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 替代Protocol buffers 的FlatBuffers:高效利用内存的序列化函数库(Unity中测试)
- 华为机试题:数据分类处理
- matlab-基础 用disp输出含有变量的句子
- SwipeRefreshLayout实现上拉下拉刷新
- 对象导论之继承
- 文章标题
- 一些jar的作用
- 第六章 Lighting Models
- A strange lift (HDU1548)
- Tensorflow: recurrent neural network (mnist basic)
- Leetcode 51. N-Queens
- c++ 字符串剪切
- Spring AOP 原理分析 part1
- VR时代的思考