【图解数据结构】排序全面总结(二)

  • 之前的排序总结(一)对插入类和交换类排序作了比较详细的总结,对于直接插入、希尔排序、冒泡排序、快速排序要求熟练掌握
  • 这篇排序全面总结(二)主要介绍选择类排序中的简单、树形和堆排序,归并排序、分配类排序的基数排序

二、选择类排序


选择类:每次从待排序的无序序列中,选择一个最大或最小的数字,放到前面,数据元素为空时排序结束

1.简单选择排序

动态演示:

算法讲解:

  1. 首先通过n-1次比较,从n个记录中找出最小值,将它与第一个元素交换
  1. 再通过n-2次比较,从剩余的n-1个记录中找出次小的值,将它与第二个记录交换
  1. 重复上述操作n-1,排序完成

代码:

void SelectSort(RecordType r[], int length)

/对记录数组r做简单选择排序,length为数组的长度/

{

int i,j,k; int n; RecordType x; n=length;

for ( i=1 ; i<= n-1; ++i)

{

k=i;

for (j=i+1 ; j<= n ; ++j)

if (r[j].key < r[k].key ) k=j;

if ( k!=i)

{

x= r[i]; r[i]= r[k]; r[k]=x;

}

}

} /* SelectSort */

特点:

  • 不稳定排序
  • 时间复杂度O(n*n), 空间复杂度O(1)

2.树形选择排序

静态演示:

算法讲解:

  1. 最下面一行21 25 49 25 16 08 63是给定需要从小到大排序的数字
  1. 相邻的两个选出一个最小的向上移一层,只有一个的补一个值无穷大的数
  1. 倒数第二层再次两两组合,直到最顶端
  1. 此时,最顶端08就是值最小的数,输出08,把所有08至为无穷大
  1. 再次选出一个最小值,以此类推

特点:

  • 算法不作要求
  • 稳定排序, 增加额外的存储空间
  • 时间复杂度O(nlogn),空间复杂度O(n-1)

3.堆选择排序

动态演示:

算法讲解:

  1. 根结点值最大的叫大顶堆,根结点值最小的叫小顶堆,上图就是一个构造大顶堆的图
  1. 从最后一层开始,如果孩子结点的值比父亲结点大,那么就交换位置
  1. 一层层向上推,直到根结点值最大

建立初始堆:

void crt_heap(RecordType r[], int length )

/对记录数组r建堆,length为数组的长度/

{

int i,n;

n= length;

for ( i=n/2; i >= 1; --i) /* 自第[n/2]个记录开始进行筛选建堆 */

sift(r,i,n);

}

调整堆:

void sift(RecordType r[], int k, int m)

/* 假设r[k…m]是以r[k]为根的完全二叉树,且分别以r[2k]和r[2k+1]为根的左、右子树为大根堆,调整r[k],使整个序列r[k…m]满足堆的性质 */

{ RecordType t; int i,j; int x; int finished;

t= r[k]; /* 暂存"根"记录r[k] */

x=r[k].key; i=k; j=2*i;

finished=FALSE;

while( j<=m && !finished )

{

if (j<m && r[j].key< r[j+1].key ) j=j+1; /* 若存在右子树,

且右子树 根的关键字大,则沿右分支"筛选" */

if ( x>= r[j].key) finished=TRUE; /* 筛选完毕 */

else

{ r[i] = r[j]; i=j; j=2i; } / 继续筛选 */

}

r[i] =t; /* r[k]填入到恰当的位置 */

}

堆排序:

void HeapSort(RecordType r[],int length)

/* 对r[1…n]进行堆排序,执行本算法后,r中记录按关键字由大到小有序排列 */

{

int i,n; RecordType b;

crt_heap(r, length); n= length;

for ( i=n ; i>= 2; --i)

{

b=r[1]; /* 将堆顶记录和堆中的最后一个记录互换 */

r[1]= r[i];

r[i]=b;

sift(r,1,i-1); /* 进行调整,使r[1…i-1]变成堆 */

}

} /* HeapSort */

特点:

  • 堆选择是树形的改进,空间占用较小
  • 不稳定排序,适合n值较大的排序
  • 时间复杂度O(n*logn),空间复杂度O(1)

三、归并排序


法一:

  • 将整体数字一分为二,逐层细分
  • 细分完成后,每一块进行排序,直到整体有序

法二:

  • 将一串序列,相邻的两个归并到一起排序,再次把相邻两个有序的归并块再次排序,直到最后有序(优先推荐这种算法)

代码:

void MergeSort ( RecordType r[], int n) /* 对记录数组r[1…n]做归并排序 */

{

MSort ( r, 1, n, r);

}

void MSort(RecordType r1[], int low, int high, RecordType r3[])

/* r1[low…high]经过排序后放在r3[low…high]中,r2[low…high]为辅助空间 */

{

int mid; RecordType r2[20];

if (low==high) r3[low]=r1[low];

else

{

mid=(low+high)/2;

MSort(r1,low, mid, r2);

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
存中…(img-LjgCZ85I-1715776904624)]

[外链图片转存中…(img-kf71B4RJ-1715776904624)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值