IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 选择排序和堆排序(C语言实现) -> 正文阅读

[数据结构与算法]选择排序和堆排序(C语言实现)

选择排序(这里实现升序)

实现思想:遍历数组找出最大或最小的数,交换到数组末尾(最大)或者数组起始位置(最小),直到数组完成有序。

动图演示(演示的是找最小的)

?void Swap(int* a, int* b)//传址,才能完成交换,否则形参不会改变实参。
{
?? ?int tmp = *a;
?? ?*a = *b;
?? ?*b = tmp;//交换函数
}
void SelectSort(int* a, int n)
{
?? ?int begin = 0;
?? ?int i = 0;
?? ?while (begin < n)
?? ?{
?? ??? ?int min = begin;//记录最小值下标,min从begin位置开始找数组未完成排序的最小值
?? ??? ?for (i = begin; i < n; i++)
?? ??? ?{
?? ??? ??? ?if (a[min] > a[i])
?? ??? ??? ?{
?? ??? ??? ??? ?min = i;//更新min位置
?? ??? ??? ?}
?? ??? ?}
?? ??? ?Swap(&a[begin], &a[min]);
?? ??? ?begin++;//第一轮排序后,数组最小值已经完成排序,begin++,排序区间往后移
?? ?}
}

这里可以优化一点,循环找最小位置的下标同时把最大位置的下标也找出来,最小的往前交换,最大的往后交换,(begin++,end--)区间改变,这样效率快一倍,但是有特殊情况要处理

void SelectSort(int* a, int n)
{
?? ?int begin = 0;//需要排序数组开始位置
?? ?int end = n - 1;//需要排序数组最后位置
?? ?int i = 0;
?? ?while (begin < end)//begin=end,一个元素不需要处理
?? ?{
?? ??? ?int min = begin;//记录最小值下标
?? ??? ?int max = begin;//记录最大值下标
?? ??? ?for (i = begin; i <= end; i++)
?? ??? ?{
?? ??? ??? ?if (a[min] > a[i])
?? ??? ??? ?{
?? ??? ??? ??? ?min = i;//更新min位置
?? ??? ??? ?}
?? ??? ??? ?if (a[max] < a[i])
?? ??? ??? ?{
?? ??? ??? ??? ?max = i;//更新mxa位置
?? ??? ??? ?}
?? ??? ?}
?? ??? ?Swap(&a[begin], &a[min]);//这里先交换最小值位置与begin位置元素
?? ??? ?if (max == begin)//判断一下最大值是否在begin位置上
?? ??? ?{
?? ??? ??? ?max = min;//如果是,交换后,最大值就在min下标位置
?? ??? ?}
?? ??? ?Swap(&a[end], &a[max]);
?? ??? ?begin++;
?? ??? ?end--;
?? ?}
}
?

时间复杂度最好最坏都是O(N^2)? 空间复杂度O(1)。?

堆排序?

实现思想,如果排升序,得先建一个大堆,在通过向下调节完成排序。

建堆

向下调节算法
若想将其调整为小堆,那么根结点的左右子树必须都为小堆。
若想将其调整为大堆,那么根结点的左右子树必须都为大堆。

所以我们得最后一个非叶子节点的左右孩子节点开始调堆。

思想实现(建大堆)

向下调整算法思想

1.从根结点处开始,找出左右孩子大的那个节点
2.大的节点与父亲节点比较
? ? 若大的孩子比父亲节点还要大,则与父亲节点位置交换,并让这个节点为新的父亲节点,继续向下调整直到叶子节点为止,
?若大的孩子比父亲小,则不需处理了,调整完成,整个树已经是大堆了。

?void AdjustHeapDown(int* a, int size, int parent)
{
?? ?int child = parent * 2 + 1;? //左孩子下标
?? ?while (child < size)//child>=size时,已经不在堆中了
?? ?{
?? ??? ?if (child + 1 < size && a[child + 1] > a[child])//child+1<size表示右孩子存在
?? ??? ?{
?? ??? ??? ?child++;//表示右孩子的值大于左孩子的值,与父亲节点比较的值是右孩子
?? ??? ?}
?? ??? ?if (a[child] > a[parent])
?? ??? ?{
?? ??? ??? ?Swap(&a[child], &a[parent]);//交换父亲孩子节点位置
?? ??? ??? ?parent = child;//父亲迭代到该孩子节点
?? ??? ??? ?child = parent * 2 + 1;//下一个需要比较的孩子节点位置
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?break;//已经满足堆的条件,跳出本次循环
?? ??? ?}
?? ?}
}

有了向下调整思想,怎样将一个任意的二叉树调成堆呢??

因为要左右节点都满足堆的性质,才能向下调整,那我们就可以从第一个非叶子节点下标开始调节,直到调到根结束。

//n-1是最后一个节点位置,公式法求该位置的父亲节点位置,parent=(child-1)/2。
??for (int i = (n - 1 - 1) / 2; i >= 0; i--)// i=0时,左右都满足大堆,最后一次从根节点调
??{
?? ???AdjustHeapDown(a, n, i);//n是二叉树的节点个数
??}

建堆的时间复杂度 (每层节点数*向下调节次数)

最后一层叶子节点不需要向下调节,所以只需要调到倒数第二层节点

堆排序

思想实现:

1.堆顶元素与最后一个元素交换

2.从根位置执行向下调整算法,但是此时最后一个位置不属于向下调整算法区间(此时该值已经排好),通过end--,调整区间往前移,重复执行1,2,直到end=0时(区间只有一个节点),完成排序。

void HeapSort(int* a, int n)
{

? ? //建堆
?? ?for (int i = (n - 1 - 1) / 2; i >= 0; i--)
?? ?{
?? ??? ?AdjustHeapDown(a, n, i);
?? ?}

? ?
?? ?int index = n - 1;//最后一个元素位置
?? ?while (index > 0)
?? ?{
?? ??? ?Swap(&a[0], &a[index]);
?? ??? ?AdjustHeapDown(a, index, 0);
?? ??? ?index--;
?? ?}
}

时间复杂度为O(N*logN)? ?空间复杂度是O(1)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:59:49  更:2022-10-17 13:03:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:45:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码