排序-选择排序与堆排序

文章目录

    • 一、选择排序
    • 二、堆排序
    • 三、时间复杂度
    • 四、稳定性


一、选择排序

思想:
将数组第一个元素作为min,然后进行遍历与其他元素对比,找到比min小的数就进行交换,直到最后一个元素就停止,然后再将第二个元素min,再遍历,以此下去直到最后一个数据
流程图:
在这里插入图片描述
代码实现:

//交换
void Swap(int* a,int* b) {int t = *a;*a = *b;*b = t;
}
//打印
void Print(int* arr, int n) {for (int i = 0;i < n; i++)printf("%d ", arr[i]);
}
//直接选择排序
void SelectSort(int* arr, int size) {for (int i = 0; i < size; i++){int min = i;//从第一个开始//每次从i+1的位置开始就不会影响到前面的了for (int j = i+1; j < size; j++) {//比较if (arr[min] > arr[j])min =j;//记录下标}Swap(&arr[i], &arr[min]);//交换}}
int main() {int arr[] = { 43152};
SelectSort(arr, sizeof(arr) / sizeof(arr[0]));
Print(arr, sizeof(arr) / sizeof(arr[0]));return 0;
}

运行结果:
在这里插入图片描述
选择排序优化:
我们可以设置一个min和一个max,将小的放到左边,大的放到右边,我们再设置两个控制左右两边下标的变量p,q,当它们相遇时就结束。
流程图:
在这里插入图片描述
特殊情况:max的位置等于p时,我们先交换arr[p]和arr[min],但是max指向p这个位置,但是p这位置的值已经改变了,这时我们就要进行纠正,将max=min,这样才能成功找到原来在p位置的值
如:
在这里插入图片描述
代码实现:

//交换
void Swap(int* a,int* b) {int t = *a;*a = *b;*b = t;
}
//打印
void Print(int* arr, int n) {for (int i = 0;i < n; i++)printf("%d ", arr[i]);
}
//优化选择排序void SelectSort1(int* arr, int size) {int p = 0, q = size-1;//p指向数组开头,q指向数组最后一个位置while (p < q) {//当错过或者相遇就结束int min = p, max = p;//迭代位置for (int i = p; i <= q; i++){if (arr[min] > arr[i])//找到最小值min = i;if (arr[max] < arr[i])//找到最大值max = i;}Swap(&arr[min], &arr[p]);//交换if (max == p)//5 2 3 4 1//判断是否要纠正max = min;Swap(&arr[max], &arr[q]);//交换p++, q--;}
}
int main() {int arr[] = { 4,3,1,5,2 };SelectSort1(arr, sizeof(arr) / sizeof(arr[0]));Print(arr, sizeof(arr) / sizeof(arr[0]));return 0;
}

运行结果:
在这里插入图片描述

二、堆排序

堆:

结构性:用数组表示的完全二叉树;
有序性:任一结点的关键字是其子树所有结点的最大值(或最小值)
“最大堆(MaxHeap)”,也称“大顶堆”,即最大值所有父亲大于等于孩子
“最小堆(MinHeap)”,也称“小顶堆”,即最小值所有父亲小于等于孩子

小堆:堆顶数据是最小的,并且所有节点都小于左右子树
在这里插入图片描述

大堆:堆顶数据是最大的 ,并且所有节点都大于左右子树
在这里插入图片描述
用堆来实现排序:
(1)使用向下调整算法:
前提:左右子树必须是小堆或者大堆
作用:建堆
如:
左右子树对比选择,再与根比较
在这里插入图片描述
(2)建堆
当我们要实现升序时,通过向下调整法要建大堆
建的过程:因为使完全二叉树,我们可以从最后非叶点节点开始建,直到没有节点就结束。
如:
建大堆
在这里插入图片描述
找左右子树位置:

树的左子树的下标等于根的下标*2+1,的下标等于根的下标 *2+2

建完后,我们可以将最后一个元素和第一个元素交换,然后再做向下调整即可不用重新建堆了,再让第一个元素和倒数第二个元素交换,以此类推…
为什么不建小堆呢?如果建小堆的话,用第一个根(最小值)就是数组的第一个元素了,我们不能动它,那么再让数组的第二元素重新做根,但是这样的话顺序就会被打破,又要重新建堆了,那样时间复杂度会提高(如何实现降序的话可以建小堆)

代码实现:

//交换
void Swap(int* a,int* b) {int t = *a;*a = *b;*b = t;
}
//打印
void Print(int* arr, int n) {for (int i = 0;i < n; i++)printf("%d ", arr[i]);
}
//向下调整  大堆
void AdjustDwon(int *arr,int p,int size) {int q = p;//节点位置int z = q * 2 + 1;//节点左子树,z+1就是右子树的位置了while (z<size) {//当z大于数组长度时就说明该节点不存在左右子树//判断左右子树大小,后面是判断是否有右子树if (arr[z] <arr[z + 1]&&z+1<size)z += 1;if (arr[z] > arr[q]) {//判断是否比根大Swap(&arr[z], &arr[q]);q = z;z = q * 2 + 1;//迭代}elsebreak;}
}
void  HeapSort(int* arr,  int size) {//建堆,size-1-1就是除2(求子树公式反过来用,最后减一是因为我们求的是下标)for (int i = (size - 1 - 1) / 2; i >= 0; i--) {AdjustDwon(arr, i, size);}int ned = size - 1;
//最后一个下标位置开始,和下标为0的元素交换,一直交换下去,并且交换一次就调整一次//当ned==1就证明排好了while (ned>0) {Swap(&arr[0], &arr[ned]);AdjustDwon(arr, 0, ned);//重新调整ned--;}
}int main() {int arr[] = { 4,3,1,5,2 };HeapSort(arr, sizeof(arr)/sizeof(arr[0]));Print(arr, sizeof(arr) / sizeof(arr[0]));
return 0}

运行结果:
在这里插入图片描述

三、时间复杂度

选择排序:
n-1 ,n-2…2,1
是一个等差数列求前n-1项和,粗略来算就是n^2
所以时间复杂度为O(n^2)

堆排序:
建堆:O(n)
在这里插入图片描述
向下调整的时间复杂度为:
假设树高为 h,树的结点为n,因为n=2^h-1,那么h=log(n-1)(以2为底)
所以为O(logn-1)
我们还要进行n次这个向下调整(当然在进行的过程中n是会变化的)
那么总的次数n+nlogn
所以时间复杂度为O(n
logn)

四、稳定性

稳定性:

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[4],且r[1]在r[4]之前,而在排序后的序列中,r[1]仍在r[4]之前,则称这种排序算法是稳定的;否则称为不稳定的。

选择排序:不稳定
如:
在这里插入图片描述
堆排序:不稳定
在这里插入图片描述
第一个9直接到最后了

以上就是我的分享了,如果有什么错误,欢迎在评论区留言。
最后,谢谢大家的观看!

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

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

相关文章

ES-分析器

分析器 两种常用的英语分析器 1 测试工具 #可以通过这个来测试分析器 实际生产环境中我们肯定是配置在索引中来工作 GET _analyze {"text": "My Moms Son is an excellent teacher","analyzer": "english" }2 实际效果 比如我们有下…

鸿蒙原生应用再添新丁!同花顺入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;同花顺入局鸿蒙 来自 HarmonyOS 微博12月11日消息&#xff0c;同花顺已完成#鸿蒙原生应用#beta版本&#xff0c;并正在进行全量版本开发&#xff0c;进一步丰富了#鸿蒙原生应用#的覆盖领域。同花顺作为股民和券商首选的一站式金融理财服务平台…

利用贝叶斯超参数优化,提升模型效果更科学(附Python代码)

超参数优化在大多数机器学习流水线中已成为必不可少的一步&#xff0c;而贝叶斯优化则是最为广为人知的一种“学习”超参数优化方法。 超参数优化的任务旨在帮助选择学习算法中成本&#xff08;或目标&#xff09;函数的一组最佳参数。这些参数可以是数据驱动的&#xff08;例…

聚首引领行业风潮!聚首品牌联动资源价值平台发布会正式启航

2023年12月10日&#xff0c;由杭州建筑装饰学会、浙江聚首联优材料科技有限公司主办&#xff0c;天尚设计集团、公和设计集团、铭扬工程设计集团、地标设计集团、上宸工程设计集团、华坤建筑设计院、广厦建筑设计研究院、上海传承博华建筑规划设计院、航冠工程设计院、浙江鸿能…

【小白专用】MySQL查询数据库所有表名及表结构其注释

一、先了解下INFORMATION_SCHEMA 1、在MySQL中&#xff0c;把INFORMATION_SCHEMA看作是一个数据库&#xff0c;确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名&#xff0c;数据库的表&#xff0c;表栏的数据类型与访问权 限等。在INF…

通过Jmeter压测存储过程

一、存储过程准备&#xff1a; 1、建立一个空表&#xff1a; 1 CREATE TABLE test_data ( id NUMBER, name VARCHAR2(50), age NUMBER ); 2、建立一个存储过程&#xff1a; CREATE OR REPLACE PROCEDURE insert_test_data(n IN NUMBER) ASBEGIN--EXECUTE IMMEDIATE trunca…

【docker三】Docker镜像的创建方法

目录 一、Docker镜像&#xff1a; 1、 镜像的概念 2、docker的创建镜像方式&#xff1a; 1.1、基于已有镜像进行创建&#xff1a; 1.2、基于模版创建&#xff1a; 1.3、基于dockerfile创建&#xff1a; 二、Dockerfile概述 1、Dockerfile概念&#xff1a; 2、dockerfile…

基于ssm电脑配件销售系统的设计与实现论文

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于电脑配件销售系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了电脑配件销售系统&#xff0c;它彻底改变了过…

IT圈的“鄙视链”大揭秘:从Java到Go,编程语言之战!

目录 ​编辑 Java程序员&#xff1a; 自信满满的领头羊 C语言程序员&#xff1a; 严肃的技术守护者 汇编语言程序员&#xff1a; 古老的传承者 Go语言程序员&#xff1a; 新晋的潜力股 结语&#xff1a; 编程语言&#xff0c;相互鄙视中求共存 我的其他博客 在IT圈…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-3燃烧卡路里-系统分析实例

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-3燃烧卡路里-系统分析实例 1. 数学模型2. 比例控制 Proprotional Control 1. 数学模型 2. 比例控制 Proprotional Control

排序算法:【选择排序]

一、选择排序——时间复杂度 定义&#xff1a;第一趟排序&#xff0c;从整个序列中找到最小的数&#xff0c;把它放到序列的第一个位置上&#xff0c;第二趟排序&#xff0c;再从无序区找到最小的数&#xff0c;把它放到序列的第二个位置上&#xff0c;以此类推。 也就是说&am…

【特殊文件(一)】属性文件读写实操

文章目录 属性文件特殊文件概述Properties属性文件概述Properties属性文件读取Properties属性文件写操作 属性文件 特殊文件概述 IO流是用来读、写文件中的数据。但是我们接触到的文件大部分都是普通的文本文件&#xff0c;普通的文本文件里面的数据是没有任何格式规范的&…