堆排序【C语言】

2023-10-27

堆排序

基本思想

利用堆(小顶堆)进行排序的过程,首先把待排序序列(R1,R2,…,Rn)转换成一个堆。这时,根结点具有最小值,输出根结点(可以将其与堆数组中的末尾元素交换,此时末尾元素就是最小值),然后将剩下的n-1个结点重新调整为一个堆。反复进行下去,直到剩下一个结点为止。

所以实现堆排序主要需要解决两个问题:

1.如何将n个元素的序列建成堆。

2.输出堆顶元素后,怎样调整剩余n-1个元素,使其关键字成为一个新堆。

首先讨论问题2的调整方法:当输出一个堆顶元素后,将最后一个元素送入堆顶,此时堆被破坏。将根节点与左右孩子中较小的元素进行交换,如果与左孩子交换,则破坏的是左子树堆,如果与右孩子交换,则破坏的是右子树堆。继续对不满足堆性质的子树进行上述交换操作,直到叶子结点,堆被建成。这个调整过程叫做筛选。

在这里插入图片描述

再来讨论问题1的建堆过程:对初始序列建堆的过程就是一个反复进行筛选的过程。若将n个结点序列看成一颗完全二叉树,则最后一个结点是第[n/2]个结点的孩子结点,对第[n/2]个结点为根的子树进行筛选,使之成为堆,直到根节点。如图所示的建堆过程:
在这里插入图片描述

空间复杂度:O(n)

时间复杂度:O(n lb n)

稳定性:不稳定

代码实现

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
void Input();                 //输入数组
void Output();                //输出数组
void sift(int k, int length); //将序列调成为堆
void creatHeap(int length);   //建堆
void HeapSort();              //堆排序
int arr[MAXSIZE];
int count = 0;

//将序列调整为堆
/*
   k 根结点所在的数组下标
   length 待调整序列的长度
 */
void sift(int k, int length)
{
    int i, j, t;
    int finished = 0; //标志筛选是否完成,0表示未完成
    t = arr[k];       //暂存根记录
    i = k;
    j = 2 * i; //左孩子结点
    while (j <= length && !finished)
    {
        if (j < length && arr[j] > arr[j + 1]) //若存在右子树,且右子树根的关键字小,则沿右分支筛选
            j = j + 1;
        if (t <= arr[j])
            finished = 1; //筛选完毕
        else
        {
            arr[i] = arr[j];
            i = j;
            j = 2 * i;
        } //继续筛选
    }
    arr[i] = t;
}
//建堆
void creatHeap(int length)
{
    int i, n = length;
    for (i = n / 2; i >= 1; i--)
        sift(i, n);
}

//堆排序
void HeapSort()
{
    int n, i, tmp;
    creatHeap(count);
    n = count;
    for (i = n; i >= 2; --i)
    {
        //将堆顶记录和堆中最后一个记录交换
        tmp = arr[1];
        arr[1] = arr[i];
        arr[i] = tmp;
        sift(1, i - 1); //调整堆
    }
}
//输入函数
void Input()
{
    int x, i;
    char s;
    printf("please input less than 100 numbers, end with enter:\n");
    for (i = 1; s != '\n'; i++)
    {
        scanf("%d", &arr[i]);
        s = getchar();
        count++;
    }
}

//输出函数
void Output()
{
    //每次调整堆后得出一个最小值,与最后一个元素交换
    //所以这里逆序输出可以得到记录按从小到大排列的顺序
    printf("sorted numbers:\n");
    for (int i = count; i >= 1; --i)
    {
        printf("%d\t", arr[i]);
    }
    printf("\n");
}

int main()
{
    Input();
    HeapSort();
    Output();
    system("pause");
    return 0;
}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

堆排序【C语言】 的相关文章

  • 钢条切割-递归,记忆性递归,dp

    钢条切割 方法1 递归 import java util Scanner public class Cutting public static int n 10 public static int p 1 5 8 16 10 17 17 2
  • CBU计算机硕士申请难度,电脑开机后CBU百分只百是什么问题

    公告 为响应国家净网行动 部分内容已经删除 感谢读者理解 话题 电脑开机后CBU百分只百是什么问题回答 有几点建议供您参考 一 使用360 优化大师等工具 将系统启动项进行优化 尽量不要自启动不常用的进程 如果不会就选择 一键优化 二 使用
  • assert_param的应用

    在STM32的固件库 到处都可以见到assert param 的使用 一开始见到这玩意就被打蒙了 不晓得它存在的价值 各种查询 理解综合如下 如果打开任何一个例程中的stm32f10x conf h文件 就可以看到实际上assert par
  • 记一次部署发现r2dbc连接数据库问题

    1 背景 a 项目使用R2DBC连接数据库 b 项目在自己搭建环境部署 各种组件使用自己的镜像 没有问题 在客户现场部署 mysql等使用客户服务 发现启动成功后隔几分钟数据库连接被断开 访问数据库报连接超时 2 最终原因 客户数据库服务的

随机推荐

  • go 入门学习 go 语言变量声明方式

    什么是变量 在编程语言中 为了方便操作内存特定位置的数据 我们用一个特定的名字与位于特定位置的内存块绑定在一起 这个名字被称为变量 动静态语言的区别 静态语言有别于动态语言的一个重要特征 变量声明 比如PHP 动态 解释性语言 不必须设定变
  • Unity 透视镜效果 shader模板测试实现 shader学习杂记(一)

    1 透视镜效果示例 场景中创建了三个物体 一个方块 一堵墙 一个球体 然后创建三个材质球 三个初始的shader 将三个shader分别拖给三个材质球 再把材质球拖给三个物体 给这三个物体红色 蓝色 绿色 便于观察 看一下以红色方块为透视镜
  • 成功简易编译cgal

    以前从csdn上下载的cgal 发现下载不了了 索性进行自己编译 用vcpkg 但是编译boost时中间报错 浪费大量时间 从网上查看 很多人都是源码开始编译 这是劝退的节奏么 感谢博主 CGAL编译与配置 尘埃1206的博客 CSDN博客
  • cocos2d-x for android:CCSprite 精灵动画

    setUniformsForBuiltins nodeToParentTransform kmGLGetMatrix KM GL PROJECTION matrixP kmGLGetMatrix KM GL MODELVIEW matrix
  • 数学 {罗尔中值定理}

    数学 罗尔中值定理 罗尔中值定理 定义 条件 函数满足 C a b C a b C a b
  • 面试官:Java为什么只有值传递?

    面试官爱问的一个基础问题 Java是值传递还是引用传递 想必大家都对这个问题都有自己的看法 那到底事实是怎样的 我们又该如何回答面试官这个问题呢 今天咱们就来好好分析一波 值传递 引用传递 首先 我们得先知道什么叫值传递 什么叫引用传递 知
  • Git第十八讲 Git常见问题解决

    Git常见问题解决 在使用 Git 进行版本控制时 你可能会遇到一些常见问题和错误 本文将介绍一些常见问题 并提供解决方案 以帮助你更好地使用 Git 1 Git 报错和常见问题解决方案 Git 在使用过程中可能会产生各种报错信息 这些错误
  • 刷脸支付全国范围火爆招募合伙人

    出门不带钱 买任何东西都靠手机的生活已经完全颠覆了我们对社会生活的认知 而这样改变仅仅出现3年之久 往前追溯 我们会发现 眼下的信息技术进步呈爆炸式递增的态势 刷脸支付技术的出现与应用 更是将信息生活的便捷度提升到了一个更高的档次上 除了让
  • 524. Longest Word in Dictionary through Deleting

    Given a string and a string dictionary find the longest string in the dictionary that can be formed by deleting some cha
  • [pcl::VoxelGrid::applyFilter] Leaf size is too small for the input dataset 报错解决,亲测可行

    pcl VoxelGrid applyFilter Leaf size is too small for the input dataset 报错解决 亲测可行 1 报错日志 Python pcl 点云下采样时报错如下 pcl VoxelG
  • Android 通过WebService进行网络编程,使用工具类轻松实现

    相信大家在平常的开发中 对网络的操作用到HTTP协议比较多 通过我们使用Get或者Post的方法调用一个数据接口 然后服务器给我们返回JSON格式的数据 我们解析JSON数据然后展现给用户 相信很多人很喜欢服务器给我们返回JSON数据格式
  • 软件测试/测试开发丨利用ChatGPT自动生成测试用例思维导图

    点此获取更多相关资料 简介 思维导图是一种用图形方式表示思维和概念之间关系的工具 有些公司会使用思维导图编写测试用例 这样做的优点是 1 可视化和结构化 2 易于理解 提高效率 而 ChatGPT 是无法直接生成 xmind 格式的文件的
  • webdriver.Chrome()报错:selenium.common.exceptions.WebDriverException: Message: 'chromedriver' ...

    使用selenium模块的webdriver打开谷歌浏览器的时候报错 源代码如下 from selenium import webdriver browser webdriver Chrome print type browser brow
  • 12-8 副作用与纯函数

    1 副作用 函数副作用 指当调用函数时 除了返回函数值之外 还对主调用函数产生附加的影响 例如修改全局变量 函数外的变量 或修改参数 表达式副作用 在表达式求值过程中 需要获取变量的值 但并不改变这些变量的值 这样的表达式称为无副作用的表达
  • 关于Visual Studio内登录microsoft账号白屏问题的解决办法

    如果连接常规Wi Fi无效的话可尝试以下方法 1 断开Wi Fi连接 关闭程序 2 打开手机热点 使电脑连接上 3 再次打开程序进行输入账号与密码的操作 4 此时尝试登录可有效避免白屏卡顿现象 亲测有效 PS 本人WiFi为中国电信 手机卡
  • 怎样使用Cubase进行人声消除

    所谓分离伴奏 指的就是消除人声 通常在一首歌曲的音频文件中 混音师一般都会将人声放在声像位置的正中间再输出为一个立体声音频文件 一般情况下是这样 但不代表全是这样 因此 人声的波形在该立体声音频文件的左声道和右声道中应该是相同或相似的 所以
  • 不好意思, Maven 该换了!

    相信使用Java的同学都用过Maven 这是一个非常经典好用的项目构建工具 但是如果你经常使用Maven 可能会发现Maven有一些地方用的让人不太舒服 一来Maven的配置文件是XML格式的 假如你的项目依赖的包比较多 那么XML文件就会
  • SLAM代码(三维重建)

    版权声明 本文为博主原创文章 遵循 CC 4 0 BY SA 版权协议 转载请附上原文出处链接和本声明 本文链接 https blog csdn net wendox article details 52719252 三维重建的一般步骤 特
  • 爬虫隐藏自身的ip并伪装成浏览器

    爬虫隐藏自身的ip并伪装成浏览器 使用代理访问 就是说使用代理 代理 访问url之后 再将网页的内容在传给本机的 使用代理访问 import urllib request import random url http www whatism
  • 堆排序【C语言】

    堆排序 基本思想 利用堆 小顶堆 进行排序的过程 首先把待排序序列 R1 R2 Rn 转换成一个堆 这时 根结点具有最小值 输出根结点 可以将其与堆数组中的末尾元素交换 此时末尾元素就是最小值 然后将剩下的n 1个结点重新调整为一个堆 反复