选择排序的基本思想

每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,知道所有记录排序完毕。主要有两种选择排序方法:直接选择排序(或称简单选择排序)和堆排序。

直接选择排序

基本思想

第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[n].key,即经过n-1趟排序之后,整个文件R[1 …… n]递增有序。注意,第一趟排序開始时。无序区为R[1 …… n],有序区为空。

java程序

  1. /*************************
  2. *
  3. * 直接选择排序(简单选择排序)
  4. *
  5. *************************/
  6. public class SelectSort {
  7. private void selectSort(int[] datas) {
  8. if (datas == null || datas.length < 2)
  9. return;
  10. int minValue;// 无序区最小值变量
  11. for (int i = 0; i < datas.length - 1; i++) {
  12. minValue = datas[i];// 将最小值变量初始化为无序区第一个位置上的值
  13. for (int j = i + 1; j < datas.length; j++) {
  14. if (datas[j] < minValue) {
  15. minValue = datas[j];
  16. // 交换两数值
  17. int temp = datas[i];
  18. datas[i] = minValue;
  19. datas[j] = temp;
  20. }
  21. }
  22. }
  23. }
  24. public static void main(String[] args) {
  25. int[] datas = new int[] { 8, 5, 2, 6, 9, 3, 1, 4, 0, 7 };
  26. System.out.println("********排序前********");
  27. for (int i = 0; i < datas.length; i++) {
  28. System.out.print(datas[i] + ",");
  29. }
  30. SelectSort selectSort = new SelectSort();
  31. selectSort.selectSort(datas);
  32. System.out.println("\n********排序后********");
  33. for (int i = 0; i < datas.length; i++) {
  34. System.out.print(datas[i] + ",");
  35. }
  36. }
  37. }

性能分析

  1. 平均时间复杂度为O(n2
  2. 直接选择排序属于就地排序
  3. 直接选择排序是不稳定的

堆排序

基本思想

堆排序是利用全然二叉树进行排序的方法

堆首先是一棵全然二叉树

然后满足一下条件之中的一个:

(1) Ki <= K2i 而且Ki <= K2i+1

(2) Ki >= K2i 而且Ki >= K2i+1

堆有大根堆(或根结点关键字值最大的堆)和小根堆(根结点关键字最小)之分。

大根堆排序算法的基本操作:初始化操作是将R[1 …… n]构造为初始堆;每一趟排序的基本操作是将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换。然后将新的无序区调整为堆(亦称为重建堆)。

显然仅仅须要做n-1趟排序。选出较大的n-1个关键字就可以使文件递增有序。用小根堆排序全然与此类同,仅仅只是其排序结果是递减有序的。

java程序


  1. public class HeapSort {
  2. /**
  3. * 建立大根堆
  4. *
  5. * @param datas
  6. * 待排数组
  7. * @param s
  8. * 父节点
  9. * @param length
  10. * 无序项的个数
  11. */
  12. private void creatHeap(int[] datas, int s, int length) {
  13. int temp = datas[s];
  14. for (int j = 2 * s; j <= length; j *= 2) {
  15. if (j < length && datas[j] < datas[j + 1])
  16. ++j;// j是关键字中较大的记录的下标
  17. if (temp >= datas[j])
  18. break;
  19. datas[s] = datas[j];// 将最大值赋予父节点
  20. s = j;
  21. }
  22. datas[s] = temp;// 将原父节点的值赋予拥有最大值的子节点。完毕终于的交换
  23. }
  24. /**
  25. * 堆排序
  26. *
  27. * @param datas
  28. * 待排序的数组
  29. * @param index
  30. * 待排序数组中待排项的个数
  31. */
  32. private void heapSort(int[] datas, int index) {
  33. if (datas == null || index < 2)
  34. return;
  35. for (int i = index / 2; i > 0; i--) {
  36. creatHeap(datas, i, index);
  37. }
  38. for (int i = index; i > 1; i--) {
  39. int temp = datas[i];
  40. datas[i] = datas[1];
  41. datas[1] = temp;
  42. // 对其余数值进行重建堆操作
  43. creatHeap(datas, 1, i - 1);
  44. }
  45. }
  46. public static void main(String[] args) {
  47. int[] datas = new int[10];
  48. datas[1] = 6;
  49. datas[2] = 5;
  50. datas[3] = 3;
  51. datas[4] = 1;
  52. datas[5] = 8;
  53. datas[6] = 7;
  54. datas[7] = 2;
  55. datas[8] = 4;
  56. datas[9] = 9;
  57. int index = 9;
  58. System.out.println("********排序前********");
  59. for (int i = 1; i < index + 1; i++) {
  60. System.out.print(datas[i] + ",");
  61. }
  62. HeapSort heapSort = new HeapSort();
  63. heapSort.heapSort(datas, index);
  64. System.out.println("\n********排序后********");
  65. for (int i = 1; i < index + 1; i++) {
  66. System.out.print(datas[i] + ",");
  67. }
  68. }
  69. }

性能分析

堆排序的时间主要是由建立初始堆和重复重建堆这两部分的时间开销构成,它们均是通过调用HeapSort实现的。

  1. 堆排序的最坏时间复杂度为O(nlgn)。堆排序的平均时间性能较接近于最坏性能
  2. 由于建初始堆所需的比較次数较多,所以堆排序不适宜于记录数比較少的文件
  3. 堆排序是就低排序,辅助空间为O(1)
  4. 堆排序的时间复杂度为O(nlgn),是一种不稳定的排序方法

參考资料:《数据结构与算法分析——java语言描写叙述》、《大话数据结构》

【算法拾遗(java描写叙述)】--- 选择排序(直接选择排序、堆排序)的更多相关文章

  1. 【算法拾遗(java描写叙述)】--- 插入排序(直接插入排序、希尔排序)

    插入排序基本思想 每次将一个待排序的记录按其keyword大小插入到前面已经拍好序的子文件的适当位置,直到全部记录插入完毕为止. 直接插入排序 基本思想 直接插入排序的基本操作是将一个记录插入到已排好 ...

  2. 必须知道的八大种排序算法【java实现】(二) 选择排序,插入排序,希尔算法【详解】

    一.选择排序 1.基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换:然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止. 2.实例 3.算法 ...

  3. 【特征检測】BRIEF特征点描写叙述算法

    简单介绍 BRIEF是2010年的一篇名为<BRIEF:Binary Robust Independent Elementary Features>的文章中提出,BRIEF是对已检測到的特 ...

  4. 【OpenCV新手教程之十八】OpenCV仿射变换 &amp; SURF特征点描写叙述合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/33320997 作者:毛星云(浅墨)  ...

  5. 数据结构与算法【Java】08---树结构的实际应用

    前言 数据 data 结构(structure)是一门 研究组织数据方式的学科,有了编程语言也就有了数据结构.学好数据结构才可以编写出更加漂亮,更加有效率的代码. 要学习好数据结构就要多多考虑如何将生 ...

  6. 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)

    排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列. 稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关 ...

  7. 9, java数据结构和算法: 直接插入排序, 希尔排序, 简单选择排序, 堆排序, 冒泡排序,快速排序, 归并排序, 基数排序的分析和代码实现

    内部排序: 就是使用内存空间来排序 外部排序: 就是数据量很大,需要借助外部存储(文件)来排序. 直接上代码: package com.lvcai; public class Sort { publi ...

  8. 常见排序算法(附java代码)

    常见排序算法与java实现 一.选择排序(SelectSort) 基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换:接着对不包括第一个记录以外的其他 ...

  9. 几大排序算法的Java实现

    很多的面试题都问到了排序算法,中间的算法和思想比较重要,这边我选择了5种常用排序算法并用Java进行了实现.自己写一个模板已防以后面试用到.大家可以看过算法之后,自己去实现一下. 1.冒泡排序:大数向 ...

随机推荐

  1. luogu1403 约数研究

    题目大意:给出n,求1~n所有数的约数个数的和. 将“1~n所有数的约数”的模板中的factor[i*j].push_back(i)改为FactorCnt[i*j]++,最后再求一次和即可. #inc ...

  2. Softmax回归——logistic回归模型在多分类问题上的推广

    Softmax回归 Contents [hide] 1 简介 2 代价函数 3 Softmax回归模型参数化的特点 4 权重衰减 5 Softmax回归与Logistic 回归的关系 6 Softma ...

  3. CodeForces--621A--Wet Shark and Odd and Even(数学水题)

    Wet Shark and Odd and Even Time Limit: 2000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & ...

  4. Linux Shell Scripting Cookbook 读书笔记 4

    正则, grep 1. 正则表达式  正则表达式  描述  示例 ^ 行起始标记  ^hell匹配以hell开头的行 $ 行尾标记  test$匹配以test结尾的行 . 匹配任意一个字符  hell ...

  5. OpenCASCADE 包说明

    转载地址:http://www.cppblog.com/eryar/archive/2012/06/30/180916.html 一.简介 Introduction to Package gp gp是 ...

  6. 自制滑杆slider

    一.效果图 二.HTML结构 <div id="d2"> <p>自制可拖动滑块:</p> <div id="out"& ...

  7. 全局变量变为局部变量 & MVC思想

    1 函数中的全局变量如何变成局部变量? 全局变量之间会相互骚扰.所以在代码中不要用全局变量.ES6之前只有函数里面有全局变量. 全局变成局部变量怎么变? 把代-放在一个函数如中,再.call()执行一 ...

  8. CI中的分页

    根据MVC的思想,分页是需要传数据到模型中,把页码传过去,在模型中根据页码分配: 更多分页类函数可以通过CI手册的分页类查看: $this -> load ->library('pagin ...

  9. PHP开发笔记(二)PHP的json_encode和json_decode问题

    解决PHP的json_encode问题之前,先了解一下PHP预定义常量http://php.net/manual/zh/json.constants.php. 用PHP的json_encode来处理中 ...

  10. wpf ComboBox 获取选中项的文本内容

    一:根据数据源类型获取选中项 类: public class Region { public int REGION_ID { get; set; } public string REGION_CODE ...