排序算法总结 超、凢脫俗 2021-11-19 14:54 314阅读 0赞 2019-07-20 import java.net.Socket; import java.util.Arrays; import java.util.ConcurrentModificationException; /** * @ClassName SortDemo * @Author wangyudi * @Date 2019/7/20 14:44 * @Version 1.0 * @Description */ public class SortDemo { /** * 选择排序:每次选择排列一个位置 * 注意点:数组最后一个位置不需要选择 * 每次和最小值进行比较 * * @param a */ public void selectSort(Comparable[] a) { if (a == null) return; int length = a.length; if (a.length == 0 || a.length == 1) return; int min = 0;//每次选择排序中,最小数的索引值 for (int i = 0; i < length - 1; i++) { min = i;//用于记录最小值所在的索引 for (int j = i + 1; j < length; j++) { if (less(a[j], a[min])) min = j; //注意 } exch(a, i, min); } } ; /** * 插入排序:将当前指针所指的元素插入到前面的排序数组中 * 注意点:插入排序从索引为1 的元素开始插入排序 * * @param arr */ public void insertSort(Comparable[] arr) { if (arr == null) return; int length = arr.length; if (arr.length == 0 || arr.length == 1) return; for (int i = 1; i < length; i++) { for (int j = i; j > 0 && less(arr[j], arr[j - 1]); --j) { exch(arr, j, j - 1); } } } /** * 希尔排序:将数组以h为间隔分为若干个数组;解决了插入排序中,交换次数过多的情况 * 注意点:最后一次希尔排序h为1; * * @param arr */ public void hillSort(Comparable[] arr) { if (arr == null) return; int length = arr.length; if (arr.length == 0 || arr.length == 1) return; int h = 1; while (h < length / 3) h *= 3; while (h >= 1) { for (int i = h; i < length; i++) { for (int j = i; j > h - 1 && less(arr[j], arr[j - h]); j -= h) { exch(arr, j, j - h); } } h = h / 3; } } /** * 归并排序(递归):将数组不断地等分,然后归并; * 归并:将两个有序的数组归并后任然是有序数组 * 这里使用的是非原地归并,为了避免在归并排序中平频繁地创建数组,这里初始时创建了和输入数组一样大的数组 * * @param arr */ public void mergeSort(Comparable[] arr) { if (arr == null) return; int length = arr.length; if (arr.length == 0 || arr.length == 1) return; Comparable[] temp = new Comparable[length]; //用于归并的辅助数组 mergeSortCore(arr, 0, length - 1, temp); } private void mergeSortCore(Comparable[] arr, int lo, int hi, Comparable[] temp) { if (lo >= hi) return; int mid = lo + (hi - lo) / 2; mergeSortCore(arr, lo, mid, temp); mergeSortCore(arr, mid + 1, hi, temp); merge(arr, lo, mid, hi, temp); } private void merge(Comparable[] arr, int lo, int mid, int hi, Comparable[] temp) { for (int i = lo; i <= hi; i++) { temp[i] = arr[i]; } int p = lo; int q = mid + 1; for (int i = lo; i <= hi; i++) { if (p > mid) arr[i] = temp[q++]; else if (q > hi) arr[i] = temp[p++]; else if (less(arr[p], arr[q])) arr[i] = temp[p]; else arr[i] = temp[q]; } } /** * 归并排序(自下而上):从11 22 44合并数组 */ public void mergeSort2(Comparable[] arr) { if (arr == null) return; int length = arr.length; if (arr.length == 0 || arr.length == 1) return; Comparable[] temp = new Comparable[length]; for (int size = 1; size < length; size *= 2) { //遍历所有长度的子数组 1,2,4,8…… for (int i = 0; i < length - size; i = i + 2 * size) { //遍历所有需要遍历的两个子数组 merge2(arr, i, i + size - 1, min(i + 2 * size - 1, length - 1), temp); } } } private int min(int a, int b) { return a < b ? a : b; } private void merge2(Comparable[] arr, int lo, int mid, int hi, Comparable[] temp) { for (int i = lo; i <= hi; i++) { temp[i] = arr[i]; } int p = lo; int q = mid + 1; for (int i = lo; i <= hi; i++) { if (p > mid) arr[i] = temp[q++]; else if (q > hi) arr[i] = temp[p++]; else if (less(arr[p], arr[q])) arr[i] = temp[p]; else arr[i] = temp[q]; } } /** * 快速排序:选择排序数组中的一个数,然后对其进行分割 */ public void quickSort(Comparable[] arr) { if (arr == null) return; int length = arr.length; if (arr.length == 0 || arr.length == 1) return; quickSortCore(arr, 0, length - 1); } public void quickSortCore(Comparable[] arr, int lo, int hi) { if (lo >= hi) return; int mid = partition(arr, lo, hi); quickSortCore(arr, lo, mid - 1); quickSortCore(arr, mid + 1, hi); } /** * 将数组切分,并返回切分比较值所在的索引 * * @param arr * @param lo * @param hi * @return */ private int partition(Comparable[] arr, int lo, int hi) { Comparable v = arr[lo]; int i = lo; int j = hi + 1; while (true) { //i指向数组范围内比基准数大的值,或者数组最后一个元素 //j指向数组范围内比基准数小的值,或者数组第一个元素 while (arr[++i].compareTo(v) <= 0) if (i == hi) break; while (arr[--j].compareTo(v) >= 0) if (j == lo) break; if (i >= j) break; exch(arr, i, j); } exch(arr, lo, j); return j; } /** * 三向切分 快速排序方法:适用于数组中有大量相同元素的排序算法 * 将数组分为 小于 等于 大于三部分 * partition3Way 需要两个指针和遍历指针 */ public void quickSort3Way(Comparable[] arr) { if (arr == null) return; int length = arr.length; if (arr.length == 0 || arr.length == 1) return; quickSort3WayCore(arr, 0, length - 1); } private void quickSort3WayCore(Comparable[] arr, int lo, int hi) { if (lo >= hi) return; int[] result = partition3Way(arr, lo, hi); quickSort3WayCore(arr, lo, result[0] - 1); quickSort3WayCore(arr, result[1] + 1, hi); } private int[] partition3Way(Comparable[] arr, int lo, int hi) { int lp = lo;//指向小于部分尾部 int gp = hi;//指向大于部分头部 Comparable value = arr[lo]; int i=lo+1; while(i<=gp) { //i是用于遍历数组来切分的指针变量 int cmp = arr[i].compareTo(value); if (cmp > 0) { //arr[i]比较大 exch(arr, i, gp--); } else if (cmp < 0) { exch(arr, lp++, i++); //注意,这里会调节数组 } else{ i++; } } int[] result = new int[]{lp, gp}; return result; } /** * 堆排序:用一个数组实现最大堆(最大优先队列) * 注意点:保存数据的第一个索引没有使用 * 这里实现的堆排序中,使用了数组的第一个元素 k 2k+1 2k+2 * * @param arr */ public void heapSort(Comparable[] arr) { if (arr == null) return; int length = arr.length; if (arr.length == 0 || arr.length == 1) return; //堆有序化, 从倒数第二排开始 sink for (int i = (length - 1) / 2; i >= 0; i--) { sink(arr, i, length - 1); } //排序,将堆顶最大的数交换到数组的末尾,然后堆顶数据sink int last = length - 1; while(last!=0){ exch(arr,0,last--); sink(arr,0,last); } } private void sink(Comparable[] arr, int k, int last) { while ((2 * k + 1) <= last) { //有子节点 int j = 2 * k + 1; if ((j + 1) <= last) if (arr[j].compareTo(arr[j + 1]) < 0) j += 1; //去子节点中的较大者 if (arr[k].compareTo(arr[j]) >= 0) break; exch(arr, k, j); k = j; //替换比较对象索引 } } /** * 交换 * * @param a * @param i * @param j */ public static void exch(Comparable[] a, int i, int j) { Comparable temp; temp = a[i]; a[i] = a[j]; a[j] = temp; } /** * 比较 * * @param a * @param b * @return */ public static boolean less(Comparable a, Comparable b) { return a.compareTo(b) < 0; } /** * 显示当前数组 * * @param a */ public static void show(Comparable[] a) { System.out.println(Arrays.toString(a)); } /** * 判断数组是否有序 * * @param a * @return */ public static boolean isSorted(Comparable[] a) { for (int i = 0; i < a.length - 1; i++) { if (a[i].compareTo(a[i + 1]) > 0) { System.out.println("false"); return false; } } System.out.println("true"); return true; } } class TestCase { public static void main(String[] args) { SortDemo sortDemo = new SortDemo(); Integer[] a = new Integer[]{34, 2, 5, 4, 45, 6, 22}; // sortDemo.selectSort(a); // SortDemo.isSorted(a); // sortDemo.insertSort(a); // SortDemo.isSorted(a); // sortDemo.mergeSort(a); // SortDemo.isSorted(a); // sortDemo.mergeSort2(a); // SortDemo.isSorted(a); // sortDemo.quickSort(a); // SortDemo.isSorted(a); // sortDemo.quickSort3Way(a); // SortDemo.isSorted(a); // sortDemo.heapSort(a); // SortDemo.isSorted(a); } } 转载于:https://www.cnblogs.com/youzoulalala/p/11218540.html
相关 排序算法总结 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。 我们这里说说八 ﹏ヽ暗。殇╰゛Y/ 2022年07月15日 22:38/ 0 赞/ 156 阅读
相关 算法-排序算法总结 冒泡排序 朴素冒泡排序 反复扫描待排序序列,在扫描的过程中顺次比较相邻的两个元素的大小,若逆序就交换位置。第一趟,从第一个数据开始,比较相邻的两个数据,(以升序为例 短命女/ 2022年06月09日 01:58/ 0 赞/ 267 阅读
相关 排序算法总结 冒泡排序 时间复杂度为O(n2),最好情况下为O(n),空间复杂度为O(1)。稳定的 冒泡排序总结: void swap(int &a,int 比眉伴天荒/ 2022年05月18日 09:36/ 0 赞/ 185 阅读
相关 排序算法总结 排序算法总结 <table> <thead> <tr> <th align="center">排序算法</th> <th align="cent ╰半橙微兮°/ 2022年04月12日 08:57/ 0 赞/ 176 阅读
相关 排序算法总结 1.插入排序算法(附伪代码和C源码) 插入排序原理:从第i=2位开始到数组长度|A|截至。将当前i的值key取出来,从i开始从后往前\[1, i-1\]寻找小于(大 淩亂°似流年/ 2022年01月06日 04:09/ 0 赞/ 258 阅读
相关 排序算法总结 最近在看左神的算法视频,随便记录下自己的学习心得,方便以后review,也让大家对基本的排序算法有个了解。 冒泡排序 > 冒泡排序(英语:Bubble Sort)是一种 红太狼/ 2022年01月06日 01:51/ 0 赞/ 288 阅读
相关 排序算法总结 O(n2)的冒泡,选择,插入,先不贴,先贴归并,快排,堆排, O(nlog(n)) 归并排序 二路归并递归写法:时间O(nlog(n)),稳定,总时间O(nlog),空间 分手后的思念是犯贱/ 2021年12月21日 01:21/ 0 赞/ 248 阅读
相关 排序算法总结 1.冒泡排序 > 冒泡算法思想: > 1.从左到右依次比较相邻的元素。如果第一个比第二个大,就交换他们两个,等全部执行完,最后的元素就是最大的数,这 今天药忘吃喽~/ 2021年12月13日 15:01/ 0 赞/ 264 阅读
相关 排序算法总结 常见排序算法评估 时间复杂度 O(n2):冒泡排序、选择排序、插入排序 O(nlogn):归并排序、快速排序、堆排序、希尔排序 O(n):计数排序、基数排序 ╰半橙微兮°/ 2021年12月13日 14:13/ 0 赞/ 283 阅读
相关 排序算法总结 2019-07-20 import java.net.Socket; import java.util.Arrays; import java.uti 超、凢脫俗/ 2021年11月19日 14:54/ 0 赞/ 315 阅读
还没有评论,来说两句吧...