选择排序:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。

选择排序正如定义所讲,在数组查询出最小值,然后放在此次循环开始位置(前一次循环已经获取比它更小的值放在前面)。

简单选择排序就是单纯的从数组中一次一次循环获取到最小值,放到循环位置。而堆排序正如名字,是从一个堆中选择,然后放在堆的循环开始位置,所以重点就是如何争取获取堆(分组)。

一、简单选择排序

1、算法思想

正如图上所示,每次选择最小值,然后放在本次循环的开始位置。

2、代码

//选择排序
void SortAlgorithm::SelectSort(pSqlList pList)
{int i,j,min;printf("开始验证选择排序");//选择排序和低级冒泡排序很像,关键就是在比较时,低级冒泡进行数据交换,而选择排序进行记录,最后只交换一次for (i =0;i<pList->length;i++){min = i;for(j = pList->length-1;j>=i;j--){//注意数组坐标,千万别溢出if (pList->SqlArray[min] > pList->SqlArray[j]){min = j;}}//最后进行交换,先选择最小的,最后一次交换
        swap(pList,i,min);PrintSqlList(pList);}}

简单选择排序算法海华丝比较简单,关键点就是遍历寻找最小记录,然后入循环开始位置进行交换。

二、堆排序

1、堆排序概念

堆排序是首先引入完全二叉树的概念,就是构建完全二叉树,前提是完全二叉树是有特点的,也就是大根堆和小根堆。

上图是完全二叉树,在完全二叉树中有几个性质:

设当前元素在数组中以R[i]表示,那么,
(1) 它的左孩子结点是:R[2*i+1];
(2) 它的右孩子结点是:R[2*i+2];
(3) 它的父结点是:R[(i-1)/2];

(4) R[i] <= R[2*i+1] 且 R[i] <= R[2i+2]。

大根堆:每个结点的关键字都不小于其孩子结点的关键字。

小根堆:每个结点的关键字都不大于其孩子结点的关键字。

2、算法思想

(1)根据初始数组去构造初始堆,默认是大根堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。

(2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。

上述算法是个循环操作,先构建,然后交换输出,最后调整余下的为大根堆,其实就是寻找最大值,其实只需要左右两个结点,那个比较大,就获取那个,所以调整堆排序也是比较简单,就是比较左右结点,获取最大值

第一步:构建大根堆

第二步、输出、调整

3、代码

////堆排序
void SortAlgorithm::HeapSort(pSqlList pList)
{//循环构建堆for (int i = pList->length/2;i>0;i--){AdjustHeap(pList,i,pList->length-1);}PrintSqlList(pList);for (int i = pList->length-1;i>1;i--){//循环输出根节点,同时再次调整为大根堆swap(pList,1,i);     //根节点位于最前面,也就是1,这样就将1最大值,放在数组后面了AdjustHeap(pList,1,i-1);PrintSqlList(pList);}
}
inline void SortAlgorithm::AdjustHeap(pSqlList pList,int start,int length)
{int temp  = pList->SqlArray[start];  //这是分支节点,然后比较它的分支节点,也就是2ifor (int i = 2*start;i<length;i = i*2){//获取左右结点中比较大的值的坐标if (i<length && pList->SqlArray[i] < pList->SqlArray[i+1]){i++;}//如果根节点本来就大,无序调整if (temp > pList->SqlArray[i]){break;}//交换值,将左右结点大值放在根节点pList->SqlArray[start] = pList->SqlArray[i];start = i;}//将开始需要比较的值,放在最后交换出的位置上pList->SqlArray[start] = temp;}

4、代码分析

程序中一开始构建,调整大根堆,最大值是length/2,因为从完全二叉树的概念上分析:

在上图中大根堆的建立,就是调整前四个元素的位置,就是放再分支节点上还是叶子结点上,所以只要输入4即可。

一开始大根堆,发现是90在最前面。

首先,将位于第一位(根节点树最大),然后和最后一位交换,然后调整前8位(第九位已经是最大了)。

然后,再讲获取到的80,和最后一位(第九位,第十已经不需交换),然后调整前7位,当然都是从1开始了。

最后经过一次次循环调整,完成算法的排序。

其中关键的思想是获取调整堆排序,比如一开始90和20交换后,20位于第一位置;此时20和左右结点中的较大值80交换,关键是后续继续拿20和后面左右结点比较,直到break,也就是找到比它小的,跳出,然后赋值。

三、性能分析

1、简单选择排序

从简单选择排序的过程来看,它最大的特点就是交换移动数据次数相当少,这样也就节约了相应的时间。分析它的时间复杂度,无论最好最差的情况,其比较次数都是一样多,第i趟排序需要进行n-i次关键字的比较,此时需要n-1 +...+1 = n(n - 1)/2次。而对于交换次数而言,当最好的时候,交换次数为0,最差的时候,也就初始降序时,交换次数为n-1次。总的时间复杂度依然为O(n2)。

尽管简单选择排序与冒泡排序同为O(n2),但简单选择排序的性能上还是要优于冒泡排序的。

2、堆排序

堆排序是一种不稳定的排序方法。

因为在堆的调整过程中,关键字进行比较和交换所走的是该结点到叶子结点的一条路径。

在程序运行时主要消耗在初始化构建堆和重建堆的反复刷选上。在初始化构建堆时,是从非终结点开始,其实比较两次,本来时n/2,这样最多对n/2进行两次比较工作,所以初始化构建大根堆是O(n)。

在调整构建堆时,第i次构建树logI(根据完全二叉树性质),需要遍历N-1记录,所以时间复杂度是O(nlogn)

转载于:https://www.cnblogs.com/polly333/p/4816828.html

浅谈数据结构-选择排序(简单、堆排序)相关推荐

  1. 数据结构—排序算法总结(插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、合并排序、计数排序)

    *排序 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作. 稳定性 在待排序的数组中,如果出现多个相同的关键字,例如:98751555512,中出现重复的数字,在 ...

  2. 10种排序算法比较(直接插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序、归并排序、基数排序、折半插入排序、2路插入排序)

    本文(所有排序算法代码+综合比较代码)链接:https://download.csdn.net/download/qq_39932172/11217572 一.比较目的: 由于<数据结构> ...

  3. java中的排序算法——简单选择排序,树形选择排序与堆排序(一)

    package com.sort; /**  * 选择排序:  * 简单选择排序,树形选择排序与堆排序  *   */ public class SelecSortDemo { /** * ----- ...

  4. 排序算法之选择排序(简单选择排序、堆排序)

    选择排序(简单选择排序.堆排序) 选择排序 简单选择排序 概念 算法实现 堆排序 概念 算法实现 后续 选择排序 选择排序的基本思想是:每一趟在待排序元素中选取关键字最小(或最大)的元素加入有序子序列 ...

  5. 数据结构之选择排序:堆排序

    选择排序:堆排序 思维导图: 堆的概念: 堆的初始化: 堆排序的算法思想: 堆排序代码实现: 堆排序的插入: 堆排序的删除: 堆排序的性能: 思维导图: 堆的概念: 根>=左右孩子节点的顺序存储 ...

  6. 【浅谈数据结构】《数据结构》Data Structure

    <数据结构>60' 一.栈(stack).队列(Queue).向量(Vector) 1.链表 带哨兵节点链表了解清楚 链表要会写,会分析.各种链表. 2.栈 LIFO(last in fi ...

  7. 【算法拾遗(java描写叙述)】--- 选择排序(直接选择排序、堆排序)

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

  8. 八大排序:冒泡排序、插入排序、希尔排序、选择排序、堆排序、归并排序、快速排序、基数排序

    [前言] 所有代码段都以升序为例,数组下标从0开始.排序的稳定性即:任意两个相等的数据,排序前后的相对位置不发生变化. [冒泡排序(Bubble Sort)] 它重复地访问过要排序的元素序列,依次比较 ...

  9. 牛客网Java刷题知识点之插入排序(直接插入排序和希尔排序)、选择排序(直接选择排序和堆排序)、冒泡排序、快速排序、归并排序和基数排序(博主推荐)...

    不多说,直接上干货! 插入排序包括直接插入排序.希尔排序. 1.直接插入排序: 如何写成代码: 首先设定插入次数,即循环次数,for(int i=1;i<length;i++),1个数的那次不用 ...

最新文章

  1. aes离线解密工具_CTF常用工具、网站、练习平台
  2. 产品思维——像产品经理一样思考
  3. java的销毁方法_销毁Spring Bean的三种方法
  4. Quartus II调用modelsim无缝仿真
  5. 2021年结婚登记创36年新低,六大原因值得注意
  6. CG CTF WEB php decode
  7. redis部署架构总结
  8. python处理xml文件_Python解析并修改XML文件
  9. Hibernate 基础配置及常用功能(二)
  10. 利用Ninject实现依赖注入
  11. 最流行的轻量级php框架,推荐20个最近很流行的优秀PHP框架
  12. Darwin Streaming Server 安装流程
  13. atitit.判断时间重叠方法总结 java c++ c#.net js php
  14. 金蝶 K3cloud 安装说明教程
  15. hsf端口_分布式服务框架HSF
  16. contiki学习笔记(六)contiki程序加载器和多线程库
  17. 8 款浏览器兼容性测试工具,看你了解几个?
  18. element-ui dialog(多弹框、嵌套弹框)被蒙版遮住
  19. 高精度乘法(正负数皆可(Bull Math)POJ)
  20. 2021-08-25王汕8.25国际黄金白银晚间价格走势分析及原油期货空单解套操作建议

热门文章

  1. datagridview设置为勾选才可编辑_使用lightroom前,做好这几项设置,有助于更好使用...
  2. mysql多数据源切换_CI 多数据库操作 切换数据库
  3. Leetcode-2 两数相加【c语言】
  4. php cachelock,巧用lock解决缓存击穿的解决方案
  5. HTML+CSS+JS实现 ❤️透明等离子球ui特效❤️
  6. 用计算机探索规律反思,用计算器探索规律教学反思
  7. conv2d的输入_pytorch1.0中torch.nn.Conv2d用法详解
  8. python3线程池爬虫_python3爬虫中多线程的优势总结
  9. 怎么分辨学校计算机sql版本,怎么筛选出每个年级每个学校有多少个班级
  10. 二级数据库access和mysql_二级数据库access和mysql