考研要求掌握的C语言程度(堆排序)1

含义

堆排序就是把数组的内容在心中建立为大根堆,然后每次循环把根顶和没交换过的根末进行调换,再次建立大根堆的过程

建树的几个公式

一个数组有n个元素

最后一个父亲节点是n/2-1;

假如父亲节点在数组的下标为a

那么左孩子节点在数组下标为2*a+1,右孩子节点在数组下标为2*a+2

大根堆在心里建树的要点

父亲节点必须大于孩子节点,孩子节点大小位置无影响

【注】数组界限问题,以及传参问题

核心代码

cpp 复制代码
//其实没有树,只不过是我们在心里根据数组层次建树来构建大根堆调整数组的排列顺序
//注意我这里的len是数组的长度,注意一下长度和数组下标间的关系
void AdjustDown(int nums[],int pos,int len)
{
    int dad = pos;
    int son = 2*dad+1;//左孩子在数组下标
    while(son < len)
    {
        if(son+1<len && nums[son]<nums[son+1])
        {
            son++;//挑选出左右孩子最大的,只需把son+1变为右孩子下标
        }
        if(nums[son]>nums[dad])//只能父亲大于孩子
        {
            swap(nums[son],nums[dad]);//交换数据
            dad =son;//把当前孩子作为父亲,重新循环
            son = 2*dad+1;
        }
        else
        {
            break;
        }
    }
}
复制代码
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
//数组
int nums[]={3,87,2,93,78,56,61,38,12,40};
void init_rand(int nums[],int len)
{
    srand(time(NULL));
    for(int i=0;i<len;++i)
    {
        nums[i]=rand()%100+1;//(1,100)
    }
}
//交换数据
void swap(int &a,int&b)
{
    int tmp = a;
    a=b;
    b=tmp;
}
void print(int nums[],int len)
{
    for(int i = 0;i<len ;i++ )
    {
        printf("%d ",nums[i]);
    }
    printf("\n");
}

//其实没有树,只不过是我们在心里根据数组层次建树来构建大根堆调整数组的排列顺序
void AdjustDown(int nums[],int pos,int len)
{
    int dad = pos;
    int son = 2*dad+1;//左孩子在数组下标
    while(son < len)
    {
        if(son+1<len && nums[son]<nums[son+1])
        {
            son++;//挑选出左右孩子最大的,只需把son+1变为右孩子下标
        }
        if(nums[son]>nums[dad])//只能父亲大于孩子
        {
            swap(nums[son],nums[dad]);//交换数据
            dad =son;//把当前孩子作为父亲,重新循环
            son = 2*dad+1;
        }
        else
        {
            break;
        }
    }
}

//待排序数组,待排序数组的长度
void heap_sort(int nums[],int len)
{
    int i;
    //建立大根堆
    //从最后一个父亲元素开始
    for(i=len/2-1;i>=0;--i)
    {
        //调整没个父亲节点为大根堆
        //数组,父亲节点所在数组的下标,数组长度
        AdjustDown(nums,i,len);
    }
    //建立大根堆之后,有序的数据是在我们内心中建的树,而不是数组,因此我们还需要把他修改为数组中
    swap(nums[0],nums[len-1]);//先交换树根和最后一个节点的数据(我这里的len代表长度)
    // print(nums,len);
    //接着再次进入建立大根堆,换数据的循环中,直到数组有序
    for(i=len-1;i>0;i--)
    {
        AdjustDown(nums,0,i);//每次从父亲节点开始(这里的i代表长度)
        swap(nums[0],nums[i-1]);//每一次交换树根和(除去数组末尾已经换过的)末尾
        // print(nums,len);
    }
    
}

int main()
{
    int len = sizeof(nums)/sizeof(nums[0]);
    init_rand(nums,len);
    heap_sort(nums,len);
    print(nums,len);
}

后序补上解析

相关推荐
Yang_jie_0319 分钟前
笔记:数据结构(顺序表)
数据结构·windows·笔记
WZF-Sang1 小时前
网络基础——2
服务器·网络·c++·学习·网络编程·php
czhaii1 小时前
串口1中断收发-C语言-MODBUS协议
c语言·开发语言
Fox爱分享1 小时前
字节二面:1000瓶酒,有一瓶是毒药,多少只老鼠可以查出来?
算法·面试·程序员
+wacyltd大模型备案算法备案1 小时前
大模型评估测试题库怎么建?风险分类、测试样本的完整方法
人工智能·算法·安全·分类·大模型·大模型备案·大模型上线登记
apihz1 小时前
随机驾考题目(C 照科一 / 科四 2000+ 题)免费API调用教程
android·java·c语言·开发语言·网络协议·tcp/ip
Fox爱分享1 小时前
字节二面智力题:100只老虎和1只羊关在一起,这只羊会不会被吃?
算法·面试·程序员
心中有国也有家2 小时前
E-Brufen 技术选型全景:Flutter + 鸿蒙 + Hive CE
hive·hadoop·学习·flutter·华为·harmonyos
xin(n_n)b2 小时前
经典题目(3):把数字翻译成字符串;兑换零钱
算法
惊鸿一博2 小时前
特征匹配+Glue Factory 框架评估特征提取与匹配算法时常用的度量标准
算法·特征匹配