大话数据结构7 - 排序

排序
1、排序:是使得一个序列成为 按关键字有序的序列的操作
特点:1.输入是一个记录集合,输出还是这个记录集合,2.针对不同的关键字进行排序,得到不同的序列
关键字可以是:主关键字、次关键字、组合关键字(多个关键字/若干数据项)
组合排序方法有2种:①先排一个,再排第二个,...,②将若干项的数据先组合作为一个整体,一次排序
注意:多个关键字的排序最终都可以转化为单个关键字的排序
2、排序算法的稳定性:针对次关键字的排序,次关键字的排序结果可能会存在不唯一的情况
稳定:排序前ri<rj,排序后ri<rj,就称该排序算法是稳定的
不稳定:排序前ri<rj,排序后ri>rj,就称该排序算法是不稳定的
注意:只要有一组关键字使用这个排序算法不稳定,该排序算法就是不稳定的
3、内排序、外排序
内排序主要2个操作:关键字比较,记录移动,注意:高效的内排序算法应该有尽可能少的比较次数和移动次数
内排序的性能:①时间性能,②辅助空间,③算法的复杂性
内排序按操作分类:插入,交换,选择,归并
4、排序算法分析
算法指标:平均情况、最好情况、最坏情况、辅助空间、稳定性
性能分析可以从几个方面看:1.时间复杂度,2.空间复杂度,3.稳定性,4.记录个数,5.移动次数
注意:不同情况应考虑不同的算法来应对

意:这里讲的就是单个关键字、线性表的内排序
这里一共讲解7种排序算法
①冒泡排序、②简单选择排序、③直接插入排序、④希尔排序、⑤堆排序、⑥归并排序、⑦快速排序
使用的数据结构是:顺序表结构(线性),技巧:r[0]作为哨兵、临时变量
经常要用到的函数/操作是:两元素交换函数
默认:按升序排序,小->大
小技巧:
a.增加一个 数组长度阀值,根据记录个数选择不同的排序方法
b.使用替换操作代替交换操作
c.使用迭代代替递归

1.简单算法:①、②、③
2.改进算法:④、⑤、⑥、⑦

1.插入排序:③、④
2.交换排序:①、⑦
3.选择排序:②、⑤
4.归并排序:⑥

1.稳定的:①、②、③、⑥
2.不稳定的:④、⑤、⑦

1、冒泡排序
概念:相邻记录的关键字两两比较,反序则交换,直到没有反序的记录为止
是一种交换排序
思路最简单
冒泡排序在实现的细节可以有多种变化
算法:双重循环:i、j
i:1->length
j:从后向前循环,小值冒出(升);从前向后循环,大值冒出(降)
优化:增加一个标记变量flag,避免因已经有序的情况下的无意义的循环比较
2、简单选择排序
概念:通过n-i次比较,从n-i+1个记录中选出min的记录,并和第i个记录交换;即先从后面的记录中找到min(升)/max(降)值,再交换
是一种选择排序
算法:双重循环:i、j
i:1->length
j:从前向后循环,小值被选出(升)
3、直接插入排序
概念:将一个记录插入到已经排序的有序表中,从而得到一个新的、记录数增加1的有序表
是一种插入排序
使用到一个临时变量r[0],需要记录后移
4、希尔排序
概念:将初始记录分组,分别进行直接插入排序,当整个序列都 基本有序时,再对全体记录进行一次直接插入排序
是一种插入排序,是对直接插入排序算法的改进
基本有序:小的关键字基本在前面,大的关键字基本在后面,不大不小的基本在中间(升)
分组:采用 跳跃分割的策略,将相距某个“增量”的记录组成一个子序列,保证分组排序后的结果是基本有序,不是局部有序
增量的选取非常关键, 注意:目前还没有总结出一种最好的增量序列
注意:增量序列的最后一个增量必须为1,增量=1即使对整个序列进行直接插入排序
不稳定:由于记录是跳跃式的移动,所以希尔排序算法是不稳定的
5、堆排序,heap sort
概念:将待排序的序列(顺序表)构造成一个大顶堆(升),成为满足关系①的顺序表,整个序列中的最大值就是堆的根结点,将根结点移动交换到堆数组末尾,将剩余的n-1个序列重新构造一个堆,可得序列中次大值,重复以上过程,反复执行,便得到了一个有序表
是一种选择排序,是对简单选择排序的一种改进,利用堆结构进行排序的方法
堆:是一种完全二叉树,大顶堆、小顶堆:每个结点的值大于等于(大顶堆)/小于等于(小顶堆)左右孩子结点的值
注意:根结点一定是堆中所有结点最大/小者
按层序遍历的方式给堆结构结点从1开始编号,结点之间满足关系①(略)
将堆结构(大顶堆、小顶堆)用层序遍历存入数组,成为满足关系①的顺序表
算法:
堆/堆结点调整函数:对指定非终端结点(非叶子结点)进行的调整
主函数:两个for循环
1.第一个是将n个元素的初始序列构建成一个大顶堆(对所有非终端结点进行的从下往上、从右到左的调整),比较多、移动多
2.第二个是交换根结点与末尾结点,再构造大顶堆(对根结点进行的调整),比较少、移动少
注意:二叉树性质5,完全二叉树的双亲结点序号为s,则它的左孩子序号一定是2s、右孩子序号一定是2s+1
不适合:由于初始构建堆所需的比较次数比较多,之后再调整堆比较次数就很少,所以堆排序不适合序列个数较少的情况
不稳定:由于记录的比较与交换是跳跃式进行,所以堆排序算法是不稳定的
6、归并排序
概念:2路归并排序,设初始序列有n个记录,可以看做是n个长度为1的有序子序列,两两归并,得到n/2个长度为2或1的有序子序列,再两两归并,如此重复,直到得到长度为n的有序序列为止
是一种归并排序,利用完全二叉树结构进行排序的方法
归并:在数据结构中的定义是,将两个或两个以上的有序表组合成为一个新的有序表
算法:2种
1.递归调用
主函数、拆分序列函数/递归函数、合并函数
2.非递归调用,迭代(推荐)
主函数、中间函数、合并函数
优缺点:占空间,但效率高且稳定
7、快速排序
概念:通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则分别对这两部分记录继续进行排序,直到整个序列有序为止
是一种交换排序,是冒泡排序的升级
枢轴(pivot):对于一个关键字,左边的值都比它小,右边的值都比它大,这个关键字就称为枢轴
小数集合、枢轴、大数集合(升)
首枢轴的选取方法(重要):①固定选取,②随机选取,③三数取中(记录的个数较少),④九数取中(记录的个数较多,推荐)
注意:快速排序算法的快慢取决于首枢轴处于整个序列的位置,潜在的性能瓶颈
算法:
采用递归调用,首枢轴的值等于中间大小,递归树是平衡的,性能最优;首枢轴的值等于最大或最小,递归树是斜树,性能最差
① 基本算法:递归调用,固定选取
主函数、递归函数、枢轴函数
②优化算法:递归调用,三数取中、九数取中
在枢轴函数中添加首枢轴的选取即可
优缺点:占空间、不稳定、对少量数据排序无优势,但因为增大了记录的比较和移动的距离,所以减少了总的比较次数和移动交换次数
不稳定:关键字的比较与交换是跳跃式进行,所以快速排序算法是不稳定的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值