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

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

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

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

一、简单选择排序

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,因为从完全二叉树的概念上分析:

image

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

image

一开始大根堆,发现是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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574310.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装php7的mysql扩展,php7安装mysql扩展的方法是什么

php7安装mysql扩展的方法&#xff1a;1、下载mysql扩展并解压&#xff1b;2、使用phpize工具初始化并进行configure&#xff1b;3、执行【make && make install】命令&#xff1b;4、编辑php.ini文件&#xff1b;5、重启服务。本文环境&#xff1a;windows10系统、php7…

iPhone屏幕尺寸、分辨率及适配

目录(?)[-] iPhone尺寸规格单位inch英吋iPhone手机宽高屏幕尺寸像素密度PPI缩放因子scale factor between logic point and device pixel1Scale起源 2UIScreenscale 3UIScreennativeScale 4机型判别Resolutions Rendering2x3x以及高倍图适配12x 23x 3高倍图文件…

鼠标移动响应php程序,jQuery实现的响应鼠标移动方向插件用法示例【附源码下载】...

本文实例讲述了jQuery实现的响应鼠标移动方向插件用法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;HTML代码如下&#xff1a;www.jb51.net jQuery响应鼠标移动*{margin:0;padding:0;}ul,li{list-style:none;}div{font-family:"Microsoft YaHei";}html,bo…

jitpack让使用第三方依赖库更简单

在开发过程中&#xff0c;使用第三方优秀依赖库是个很常见的问题&#xff0c;有的时候是maven&#xff0c;或者gradle, 或者sbt,大部分库工程&#xff0c;都会有对应的gradle,maven依赖代码&#xff0c;但是有的没有&#xff0c;尤其是使用的snapshot的依赖的时候&#xff0c;虽…

Swift - 发送消息(文本,图片,文件等)给微信好友或分享到朋友圈

通过调用微信提供的API接口&#xff0c;我们可以很方便的在应用中发送消息给微信好友&#xff0c;或者分享到朋友圈。在微信开发平台&#xff08;https://open.weixin.qq.com&#xff09;里&#xff0c;提供了详细的说明文档和样例。但由于提供的样例是使用Objective-C写的&…

linux怎么改程序图标,如何在Ubuntu Unity上修改应用程序图标

这篇文章将教大家在Ubuntu Unity上修改应用程序图标&#xff0c;这个教程适合于Ubuntu 14.04, Ubuntu 13.10, Ubuntu 12.04 等使用Unity作为默认桌面环境的发行版。在Unity桌面环境&#xff0c;程序启动器实际上以.desktop为后缀的文件的形式存储在电脑上&#xff0c;所以我们可…

htop linux命令详解,htop使用详解

在管理进程时通常要借助一些工具&#xff0c;比较常用的就是ps和top了&#xff1b;不过CentOS还为我们提供了一个更加强大的工具htop&#xff0c;下面就来了解一下此工具的使用方法。一、安装htophtop工具在epel源中提供&#xff0c;请自行配置epel源&#xff0c;也可以直接下载…

Android Termux安装SSH结合内网穿透实现远程SFTP文件传输

文章目录 1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 SFTP&#xff08;SSH File Transfer Protocol&#xff09;是一种基于SSH&#xff08;Secure Shell&#xff09;安全协议的文件传输协议。与FTP协议相比&#xff0c;SFTP使用了…

linux解压war包乱码,linux中zip解压乱码解决方法

在windows上压缩的文件&#xff0c;是以系统默认编码中文来压缩文件。由于zip文件中没有声明其编码&#xff0c;所以linux上的unzip一般以默认编码解压&#xff0c;中文文件名会出现乱码。有2种方式解决问题&#xff1a;1、通过unzip行命令解压&#xff0c;指定字符集unzip -O …

Android沉浸式通知栏设计

转载博客&#xff1a;http://www.2cto.com/kf/201503/381348.html Android4.4新特性&#xff0c;系统状态栏一体化。 实现的步骤主要有以下几点&#xff1a; 1.android4.4 以上版本 2.设置app全屏&#xff1a; 方法&#xff1a;在AndroidManifest.xml中设置android:theme"…

linux火狐自动更新,CentOS 7手动更新firefox | Linux系统运维联盟

这里针对的是firefox无法检测到新版本&#xff0c;需要手动升级。1.下载新版的irefox&#xff0c;一般是.tar.gz压缩包。2.tar zxvf 解压到/usr/lib64 。(只要是原版firefox文件的目录就对了)3.cd /usr/lib64/firefox4../firefox-bin 完成有的更新好之后可能会无法播放视频&a…

Servlet的学习之Request请求对象(2)

在上一篇《Servlet的学习(十)》中介绍了HttpServletRequest请求对象的一些常用方法&#xff0c;而从这篇起开始介绍和学习HttpServletRequest的常用功能。 使用HttpServletRequest可以防止盗链行为&#xff0c;什么是盗链行为&#xff0c;比如说在一个别的网站上超链接&#xf…

如何提高linux的时钟精度,Linux时钟精度提高有什么办法?

2 动态高精度时钟设计和实现动态高精度时钟设计方案借鉴了KURT-Linux思想&#xff0c;但与其不同的是提供一个与标准Linux核心时钟并行的具有精密刻度的实时时钟&#xff0c;并与原核心时钟区别开。采用X86体系CPU提供的TSC作为高精度的时间标度&#xff0c;权衡一定时间段(如一…

Java基础知识强化之网络编程笔记05:UDP之多线程实现聊天室案例

1. 通过多线程改进刚才的聊天程序&#xff0c;这样我就可以实现在一个窗口发送和接收数据了 2. 代码示例&#xff1a; &#xff08;1&#xff09;SendThread.java&#xff0c;如下&#xff1a; 1 package com.himi.udpDemo2;2 3 import java.io.BufferedReader;4 import java.…

c语言选择法排序案例,谁能给我一个c语言选择排序法的简单例子

满意答案evil83752014.02.27采纳率&#xff1a;51% 等级&#xff1a;11已帮助&#xff1a;7590人#include int main(){int array[100], n, c, d, position, swap;printf("Enter number of elements\n");scanf("%d", &n);printf("Enter %d inte…

小球进盒子C语言,N个小球放进M个盒子算法-Go语言中文社区

N个小球放入M个盒子共有多少种方法&#xff0c;并输出的算法设计&#xff1a;算法思路1 &#xff1a;暴力填充盒子每个小球都可能放入M个盒子的任意一个&#xff0c;所以直接根据小球个数做递归即可,然后将存储放入hash中排重//TODO算法思路2 &#xff1a;递归填充盒子即&#…

r语言c5.0要求因子输出,R语言中因子的创建与使用

原标题&#xff1a;R语言中因子的创建与使用因子在R语言中可以用来表示名义型变量或有序变量。名义变量一般表示类别&#xff0c;如性别&#xff0c;种族等等。有序变量是有一定排序顺序的变量&#xff0c;如职称&#xff0c;年级等等。在R语言中&#xff0c;名义变量和有序变量…

WinForm中使用AnyCAD三维控件 の 初始化

在WinForm中可以方便的集成AnyCAD.Net三维控件&#xff0c;只需要以下几部即可完成。 一、添加DLL程序集 AnyCAD.Foundation.Net.dll AnyCAD.Presentation.Net.dll AnyCAD.Exchange.Net.dll 二、初始化控件 1.首先创建一个窗体 2.在窗体上放置一个Panel用来放置三维控件 3.初始…

android l usb调试,你居然还不会手机usb调试?5个方法,让你轻松学会设置!

原标题&#xff1a;你居然还不会手机usb调试&#xff1f;5个方法&#xff0c;让你轻松学会设置&#xff01;最近有位朋友将手机连接电脑的时候&#xff0c;遇到了提示打开手机的USB调试模式&#xff0c;却不知道怎么操作。其实&#xff0c;不同手机的usb调试打开的方式都会有所…

鸿蒙os芯片,没有了芯片,华为能靠鸿蒙OS系统打出差异化吗?

原标题&#xff1a;没有了芯片&#xff0c;华为能靠鸿蒙OS系统打出差异化吗&#xff1f;华为今天要和大家说的手机产品是华为&#xff0c;在目前的市场中&#xff0c;华为手机的影响力是非常大的&#xff0c;并且获得了十分不错的销量&#xff0c;甚至在最近一段时间销量超过三…