Java排序算法总结之(三)——选择排序(简单选择排序、堆排序)
来源:互联网 发布:证书制作软件 编辑:程序博客网 时间:2024/05/29 10:03
排序方法可以分为两种:内部排序 和 外部排序
内部排序的方法很多,常用的大致可以分为:
- 插入排序(直接插入排序、折半插入排序、希尔排序)
- 交换排序(冒泡排序、快速排序)
- 选择排序(简单选择排序、堆排序)
- 归并排序
- 基数排序
选择排序
1.简单选择排序
基本思想:对数列的 n 个元素进行比较,选出最小(或者最大)的元素,与起始位置的值交换,再从余下的数据中找到最小(最大)值,放在已排序部分的末尾,直到排序完毕。
示例:选择排序的示例动画。红色表示当前最小值,黄色表示已排序序列,蓝色表示当前位置。
Java代码:(注意与冒泡排序的区别)
public class SelectSort {public static int[] sort(int[] s) {for (int i = 0; i < s.length - 1; i++) {for (int j = i + 1; j < s.length; j++) {if (s[i] > s[j]) {int temp = s[i];s[i] = s[j];s[j] = temp;}}}return s;}}效率分析:
交换操作介于0和(n-1)次之间
选择排序的比较操作为n(n-1)/2次之间
选择排序的赋值操作介于0和3(n-1)次之间。总的时间复杂度为O(n^2)
稳定性:true,相等的值的相对位置不会发生改变。
2.堆排序
堆排序(Heapsort)是指利用 堆 这种数据结构所设计的一种排序算法。
堆 分为最大堆 和 最小堆,定义为子结点的键值或索引总是小于(或者大于)它的父节点
通常堆是通过一维数组来实现的。在Java中,数组起始位置为0,访问结点的计算方法为:
- 父节点i的左子节点在位置(2*i+1);
- 父节点i的右子节点在位置(2*i+2);
- 子节点i的父节点在位置floor((i-1)/2);
排序常用最大堆来进行。
堆可以用完全二叉树来表示,又称二叉堆。任何一个数组都可以用堆来表示
使用堆排序,我们需要做三件事:
图片来源:白话经典算法系列之七 堆与堆排序
- 创建最大堆:对数组中所有数据进行重排,使其满足最大堆的定义;
- 最大堆调整:创建最大堆时需要随时对已排好的最大堆进行重排,
- 堆排序:移除位于第一个数据的根节点,将最后的元素补到第一位,然后再进行调整
public class HeapSort {public static void buildHeap(int[] s) {// 叶子结点可以看成一个堆,故建堆从最后一个父节点开始int startIndex = getParentIndex(s.length - 1);// 循环添加结点,每添加一个,就要对当前堆进行调整,使其满足最大堆for (int index = startIndex; index >= 0; index--) {maxHeapAdjust(s, s.length, index);}}/** * 最大堆调整函数 * * @param s * @param heapSize * @param parentIndex */private static void maxHeapAdjust(int[] s, int heapSize, int parentIndex) {// 计算传入结点索引的左右子结点int leftChildIndex = getLeftChildIndex(parentIndex);int rightChildIndex = getRightChildIndex(parentIndex);// 当前结点与左右结点比较,得到对应最大值的索引int max = parentIndex;if (leftChildIndex < heapSize && s[max] < s[leftChildIndex]) {max = leftChildIndex;}if (rightChildIndex < heapSize && s[max] < s[rightChildIndex]) {// 注意:此处不能写成s[parentIndex]max = rightChildIndex;}// 如果最大值不是当前结点,那么需要交换。交换后,其子结点可能不是最大堆,需要重新调整,递归if (max != parentIndex) {int temp = s[parentIndex];s[parentIndex] = s[max];s[max] = temp;maxHeapAdjust(s, heapSize, max);}}public static void heapSort(int[] s) {// 最大堆的根结点为最大值,每次与数组最后一位交换,即可获得最大值,该值不再参与堆调整// 由于交换操作破坏了最大堆结构,需要再次调整,长度需要减一// 由于之前已经是最大堆,目前只有第一个值可能不满足,调整时传入的parentIndex = 0即可for (int i = s.length - 1; i > 0; i--) {int temp = s[0];s[0] = s[i];s[i] = temp;maxHeapAdjust(s, i, 0);}}private static int getLeftChildIndex(int index) {return (index << 1) + 1;}private static int getRightChildIndex(int index) {return (index << 1) + 2;}private static int getParentIndex(int index) {return (index - 1) >> 1;}}效率分析:
堆排序的平均时间复杂度为O(nlogn),空间复杂度为O(1)。
稳定性:false.
参考文献:
选择排序-Wikipedia
0 0
- Java排序算法总结之(三)——选择排序(简单选择排序、堆排序)
- java实现排序算法之选择排序(简单选择排序和堆排序)
- 常用排序算法总结(三)----选择排序 堆排序
- java中的排序算法——简单选择排序,树形选择排序与堆排序(一)
- 八大排序算法总结之二(简单选择算法,堆排序,归并排序,基数排序)
- 八大排序算法总结之二(简单选择算法,堆排序,归并排序,基数排序)
- 排序算法--选择排序(简单选择排序、堆排序)java实现
- 【Java常用排序算法】选择排序(简单选择排序、堆排序)
- Java之8中排序(三)---简单选择排序,堆排序(java实现)
- 算法之选择排序(2)——堆排序
- java算法之五简单选择排序(选择排序)
- 排序算法(三):简单选择排序
- 排序算法 -- (三)简单选择排序
- 排序算法(三):简单选择排序
- 排序算法(1):简单选择排序和堆排序
- 排序算法之选择排序——简单选择排序
- Java基础篇之----排序(快速排序、冒泡排序、堆排序、简单选择排序、 希尔排序、直接插入排序)
- 数据结构之排序(三)——简单选择排序
- forin
- qt 进度条
- 数据结构——堆栈
- Android多分辨率适配实践【1】使用字体图标(内含两枚神器)
- ZOJ-3601-Unrequited Love【9th浙江省赛】【模拟】【STL】
- Java排序算法总结之(三)——选择排序(简单选择排序、堆排序)
- iOS9上实现3D Touch功能之快速启动
- swift 循环强引用
- 逻辑斯谛回归总结
- 设计模式(十一)代理模式Proxy(结构型)
- BIT2014级软件学院程序设计-16 魔方
- C++第一次实验
- 修改mysql的root密码?
- L GMS预置