数据结构:直接选择排序和堆排序

 直接选择排序:

这里我用两个变量同时找出最小值和最大值。

注意:若begin为最大值,maxi即为最大值的下标,若将最小值与其交换,最大值的下标此时就不再是maxi,而变为mini了,故此时要调整maxi的位置

直接选择排序的时间复杂度 O(N^2)

void PrintArray(int* a, int n)
{int i;for (i = 0; i < n; i++){printf("%d ", *(a + i));}
}
void Swap(int* a, int* b)
{int tem = *a;*a = *b;*b = tem;
}
//直接选择排序
void SelectedSort(int* a, int n)
{int begin = 0, end = n - 1;while (begin < end){int mini = begin, maxi = end;for (int i = begin; i <= end; i++){if (a[i] < a[mini])mini = i;if (a[i] > a[maxi])maxi = i;}Swap(&a[begin], &a[mini]);//如果begin与maxi重叠,需要修正maxi此时max被换到了mini的位置上if (begin == maxi)maxi = mini;Swap(&a[maxi], &a[end]);begin++;end--;}
}
void TestSelectedSort()
{int a[] = { 3,5,2,7,8,6,1,9,4,0 };SelectedSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}

堆排序: 

  • 堆的逻辑结构是一颗完全二叉树
  • 堆的物理结构是一个数组

数组下标的父子节点关系

leftchild=parent*2+1

rightchild=parent*2+2

parent=(child-1)/2

堆的两个特性:

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

建小堆

向下调整算法

前提:左右子树都是小堆

从根节点开始选出左右孩子中小的那一个,跟父亲比较,如果比父亲小就交换,然后再继续往下调

建堆的时间复杂度为O(N)。

如果左右子树不是小堆,该怎么建小堆呢?

我们可以倒着从最后一棵子树开始调,倒着走,从倒数第一个非叶子的子树开始调,即为从8开始,那如何找到8呢,只需找出最后一个数据的下标利用父子节点的关系求出即可,即(n-1)-1/2.

若是升序,应该建大堆还是小堆呢?我第一次认为是小堆,实则不然,若是小堆,小堆会把最小的数放在第一位,选择排序是通过堆来选树,最小数此时在堆顶已被选出,此时就要在剩下的树里选树,但此时新树的结构就已经乱了,之前所建的小堆已经不复存在,需要再建小堆才能选出下一个树,建堆的时间复杂度为O(N),这样建堆所带来的效率优势就没了。故升序不能建小堆

正确的应该是建大堆,将第一个数和最后一个数交换,此时最后一个数为最大的数,不把它看成是堆里面的数,前n-1个数向下调整,选出次大的数,再跟倒数第二个位置交换,以此类推,此时中间堆的结构未改变。

堆排序的时间的复杂度为O(N*logN) 

堆排序代码如下:

//堆排序
//建大堆
void Swap(int*a, int*b)
{int tem = *a;*a = *b;*b = tem;
}
//向下调整算法
void AdjustDown(int* a, int n, int root)
{int parent = root;int child = parent * 2 + 1;//默认是左孩子while (child<n){//1.选出左右孩子中最大的一个if (child+1<n&&a[child + 1] > a[child])//防止数组越界,所以要加child+1<n{child++;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}//若孩子本来就比父亲小,因为大堆的每棵树都是大堆,说明此时堆已经建好,break即可elsebreak;}
}
void HeapSort(int* a, int n)
{//把数组建成堆 倒着走for (int i = (n - 1 - 1) / 2; i >= 0; i--)//n-1为最后一个元素的下标,(n-1-1)/2即为parent{AdjustDown(a, n, i);}//排升序,建大堆int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}
void PrintArray(int* a, int n)
{int i;for (i = 0; i < n; i++){printf("%d ", *(a + i));}
}
void TestHeapSort()
{int a[] = { 3,5,2,7,8,6,1,9,4,0 };HeapSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}int main()
{TestHeapSort();return 0;
}

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

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

相关文章

关于pycharm无法进入base界面的问题

问题&#xff1a;terminal输入activate无法进入base 解决方案 1.Cortana这边找到Anaconda Prompt右击进入文件所在位置 2. 右击进入属性 3. 复制cmd.exe开始到最后的路径 cmd.exe "/K" C:\ProgramData\anaconda3\Scripts\activate.bat C:\ProgramData\anaconda3 …

系统架构设计师教程(七)系统架构设计基础知识

系统架构设计基础知识 7.1 软件架构概念7.1.1 软件架构的定义7.1.2 软件架构设计与生命周期需求分析阶段设计阶段实现阶段构件组装阶段部署阶段后开发阶段 7.1.3 软件架构的重要性 7.2 基于架构的软件开发方法7.2.1 体系结构的设计方法概述7.2.2 概念与术语7.2.3 基于体系结构的…

【Spark精讲】Spark Shuffle详解

目录 Shuffle概述 Shuffle执行流程 总体流程 中间文件 ShuffledRDD生成 Stage划分 Task划分 Map端写入(Shuffle Write) Reduce端读取(Shuffle Read) Spark Shuffle演变 SortShuffleManager运行机制 普通运行机制 bypass 运行机制 Tungsten Sort Shuffle 运行机制…

STM32F103C8T6—烧录程序

STM32F103C8T6烧录程序方法 1. ST-Link烧录程序ST-Link软件下载ST-Link软件安装程序下载 2. 串口烧录程序CH340驱动下载安装连接程序下载 1. ST-Link烧录程序 该USB驱动程序(STSW-LINK009)适用于ST-LINK/V2, ST-LINK/V2-1和STLINK-V3板及其衍生物 首先下载ST-link驱动&#xf…

Xpath注入

这里学习一下xpath注入 xpath其实是前端匹配树的内容 爬虫用的挺多的 XPATH注入学习 - 先知社区 查询简单xpath注入 index.php <?php if(file_exists(t3stt3st.xml)) { $xml simplexml_load_file(t3stt3st.xml); $user$_GET[user]; $query"user/username[name&q…

MinIO使用,文件上传和下载

MinIO使用&#xff0c;文件上传和下载 中文文档&#xff1a;https://www.minio.org.cn/docs/minio/kubernetes/upstream/index.html 官网&#xff1a;https://min.io/ 官网下载和安装&#xff1a;https://min.io/download#/kubernetes 安装 二进制文件安装 下载MinIO wg…

55 代码审计-JAVA项目注入上传搜索或插件挖掘

目录 必备知识点演示案例:简易Demo段SQL注入及预编译IDEA审计插件FindBugs安装使用Fortify_SCA代码自动审计神器使用Ofcms后台SQL注入-全局搜索关键字Ofcms后台任意文件上传-功能点测试 涉及资源&#xff1a; 我们一般针对java项目&#xff0c;进行漏洞分析的话&#xff0c;主要…

Python 函数与参数传递

一、函数的定义和调用 在python中&#xff0c;如果经常重复使用一些代码&#xff0c;可以把它们创建为一个函数&#xff0c;这可以大大减少编程工作量。用户创建的函数叫做自定义函数。定义函数时要使用def关键字&#xff0c;格式如下&#xff1a; def 函数名&#xff08;参数…

Linux+Docker+Gitee+Jenkins自动化部署.NET Core服务

目录 一、安装Jenkins 1、跟新yum包 2、查询镜像 3、拉取镜像 4、创建Jenkins工作目录&#xff0c;并将容器内目录挂载到此目录上 5、启动Jenkins容器 二、Jenkins配置 1、Jenkins安装gitee码云插件 2、创建私人令牌 3、Jenkins添加全局凭据 4、系统配置 三、构建任…

数据安全传输基础设施平台(一)

1引言 1.1项目简介 数据安全传输基础设置平台项目&#xff08;简称&#xff0c;数据传输平台&#xff09;&#xff0c;是一款基础设施类项目&#xff0c;为集团、企业信息系统的提供统一、标准的信息安全服务&#xff1b;解决企业和企业之间&#xff0c;集团内部信息数据的传…

C# WPF上位机开发(函数运行时间分析)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 上位机除了基本功能和稳定性之外&#xff0c;还有一个要注意的就是运行效率的问题。如果我们想提高软件的运行效率&#xff0c;单位时间做更多的工…

12.5,12.15AVL树更新,定义,插入

定义平衡因子为右子树高度减去左子树高度 AVL树插入分为两步&#xff1a; 按照二叉搜索树的方式插入新节点调整平衡因子 对于平衡因子的调整&#xff0c;在插入之前&#xff0c;所有节点的平衡因子分为三种情况&#xff1a;0&#xff0c;1&#xff0c;-1插入后&#xff0c;新…