【算法拾遗(java描写叙述)】--- 选择排序(直接选择排序、堆排序)
2017-06-28 12:11
471 查看
选择排序的基本思想
每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,知道所有记录排序完毕。主要有两种选择排序方法:直接选择排序(或称简单选择排序)和堆排序。
直接选择排序
基本思想
第i趟排序開始时,当前有序区和无序区分别为R[1 …… i-1]和R[i …… n](1 <= i <= n-1),该趟排序则是从当前无序区中选出关键字最小的记录R[k],将它与无序区的第一个记录R[i]交换,使R[1 …… i]和R[i+1 …… n]分别变为新的有序区和新的无序区。
由于每趟排序均使有序区中添加了一个记录,且有序区中的记录关键字均不大于无序区中记录的关键字,即第i趟排序之后R[1 …… i].keys <= R[i+1 …… n].keys,所以进行n-1趟排序之后有R[1 …… n-1].keys <= R
.key,即经过n-1趟排序之后,整个文件R[1 …… n]递增有序。注意,第一趟排序開始时。无序区为R[1 …… n],有序区为空。
java程序
/************************* * * 直接选择排序(简单选择排序) * *************************/ public class SelectSort { private void selectSort(int[] datas) { if (datas == null || datas.length < 2) return; int minValue;// 无序区最小值变量 for (int i = 0; i < datas.length - 1; i++) { minValue = datas[i];// 将最小值变量初始化为无序区第一个位置上的值 for (int j = i + 1; j < datas.length; j++) { if (datas[j] < minValue) { minValue = datas[j]; // 交换两数值 int temp = datas[i]; datas[i] = minValue; datas[j] = temp; } } } } public static void main(String[] args) { int[] datas = new int[] { 8, 5, 2, 6, 9, 3, 1, 4, 0, 7 }; System.out.println("********排序前********"); for (int i = 0; i < datas.length; i++) { System.out.print(datas[i] + ","); } SelectSort selectSort = new SelectSort(); selectSort.selectSort(datas); System.out.println("\n********排序后********"); for (int i = 0; i < datas.length; i++) { System.out.print(datas[i] + ","); } } }
性能分析
平均时间复杂度为O(n2)直接选择排序属于就地排序
直接选择排序是不稳定的
堆排序
基本思想
堆排序是利用全然二叉树进行排序的方法
堆首先是一棵全然二叉树。
然后满足一下条件之中的一个:
(1) Ki <= K2i 而且Ki <= K2i+1
(2) Ki >= K2i 而且Ki >= K2i+1
堆有大根堆(或根结点关键字值最大的堆)和小根堆(根结点关键字最小)之分。
大根堆排序算法的基本操作:初始化操作是将R[1 …… n]构造为初始堆;每一趟排序的基本操作是将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换。然后将新的无序区调整为堆(亦称为重建堆)。
显然仅仅须要做n-1趟排序。选出较大的n-1个关键字就可以使文件递增有序。用小根堆排序全然与此类同,仅仅只是其排序结果是递减有序的。
java程序
public class HeapSort { /** * 建立大根堆 * * @param datas * 待排数组 * @param s * 父节点 * @param length * 无序项的个数 */ private void creatHeap(int[] datas, int s, int length) { int temp = datas[s]; for (int j = 2 * s; j <= length; j *= 2) { if (j < length && datas[j] < datas[j + 1]) ++j;// j是关键字中较大的记录的下标 if (temp >= datas[j]) break; datas[s] = datas[j];// 将最大值赋予父节点 s = j; } datas[s] = temp;// 将原父节点的值赋予拥有最大值的子节点。完毕终于的交换 } /** * 堆排序 * * @param datas * 待排序的数组 * @param index * 待排序数组中待排项的个数 */ private void heapSort(int[] datas, int index) { if (datas == null || index < 2) return; for (int i = index / 2; i > 0; i--) { creatHeap(datas, i, index); } for (int i = index; i > 1; i--) { int temp = datas[i]; datas[i] = datas[1]; datas[1] = temp; // 对其余数值进行重建堆操作 creatHeap(datas, 1, i - 1); } } public static void main(String[] args) { int[] datas = new int[10]; datas[1] = 6; datas[2] = 5; datas[3] = 3; datas[4] = 1; datas[5] = 8; datas[6] = 7; datas[7] = 2; datas[8] = 4; datas[9] = 9; int index = 9; System.out.println("********排序前********"); for (int i = 1; i < index + 1; i++) { System.out.print(datas[i] + ","); } HeapSort heapSort = new HeapSort(); heapSort.heapSort(datas, index); System.out.println("\n********排序后********"); for (int i = 1; i < index + 1; i++) { System.out.print(datas[i] + ","); } } }
性能分析
堆排序的时间主要是由建立初始堆和重复重建堆这两部分的时间开销构成,它们均是通过调用HeapSort实现的。堆排序的最坏时间复杂度为O(nlgn)。堆排序的平均时间性能较接近于最坏性能
由于建初始堆所需的比較次数较多,所以堆排序不适宜于记录数比較少的文件
堆排序是就低排序,辅助空间为O(1)
堆排序的时间复杂度为O(nlgn),是一种不稳定的排序方法
參考资料:《数据结构与算法分析——java语言描写叙述》、《大话数据结构》
相关文章推荐
- 【算法拾遗(java描写叙述)】--- 插入排序(直接插入排序、希尔排序)
- 【算法拾遗(java描述)】--- 选择排序(直接选择排序、堆排序)
- java实现各种基础排序(冒泡排序、快速排序、直接选择排序、堆排序、直接插入排序、归并排序)
- 用JAVA实现排序算法之三:直接选择排序
- 【算法拾遗(java描述)】--- 插入排序(直接插入排序、希尔排序)
- java数据结构之插入排序(选择排序(直接选择排序、堆排序))
- java中的排序算法——简单选择排序,树形选择排序与堆排序(一)
- 算法分析-选择排序(直接选择排序 & 堆排序)
- java进阶- 经典排序(插入排序、冒泡排序、快排(分划交换排序)、直接选择排序、堆排序、合并排序)
- 我在北京找工作(二):java实现算法<1> 冒泡排序+直接选择排序
- 数据结构算法之排序系列Java、C源码实现(3)--直接选择排序
- 牛客网Java刷题知识点之插入排序(直接插入排序和希尔排序)、选择排序(直接选择排序和堆排序)、冒泡排序、快速排序、归并排序和基数排序(博主推荐)
- java版排序算法简介及冒泡排序以及优化,选择排序,直接插入排序,希尔排序,堆排序,快速排序及其优化前言 2 分类 2 稳定性 3 时间复杂度 4 Java实现版本 5 1、冒泡排序 6 2、选择排序
- 算法-排序-选择排序(直接选择和堆排序)
- 算法 排序算法之选择排序--直接选择排序和堆排序
- 我在北京找工作(二):java实现算法<1> 冒泡排序+直接选择排序
- java中各种常用排序实现(直接插入排序、直接选择排序、堆排序、冒泡排序、快速排序和归并排序)
- 数据结构 JAVA描述(十一) 选择排序(直接选择排序,树形选择排序,堆排序)
- JAVA数据结构 直接选择排序
- java基本算法总结(冒泡排序、选择排序、插入排序)