当前位置: 首页 > news >正文

C语言实现堆排序

#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#include<string.h>
// 定义元素类型为整型
typedef int ElemType;

// 定义静态表结构体
typedef struct{
    ElemType *elem;        // 动态分配的数组指针
    int TableLen;          // 表长度
} SSTable;

// 初始化静态表
void STInit(SSTable &ST, int len) {
    ST.TableLen = len;     // 设置表长度
    ST.elem = (ElemType *)malloc(sizeof(ElemType)*ST.TableLen); // 分配内存
    int i;
    srand(time(NULL));      // 使用当前时间作为随机数种子
    for(i = 0; i < ST.TableLen; i++){ // 循环初始化数组元素
        ST.elem[i] = rand()%100;      // 随机填充元素(0-99)
    }
}

// 打印静态表内容
void STPrint(SSTable ST){
    for(int i = 0; i < ST.TableLen; i++){
        printf("%3d",ST.elem[i]); // 打印元素,右对齐,总宽度为3个字符
    }
    printf("\n");                 // 换行
}

// 交换两个元素的值
void swap(ElemType &a, ElemType &b){
    ElemType temp;               // 创建临时变量
    temp = a;                    // 保存第一个元素
    a = b;                       // 将第二个元素赋给第一个
    b = temp;                    // 将临时变量中的值(原第一个元素)赋给第二个
}

// 调整堆,使得子树满足最大堆性质
void AdjustDown(ElemType A[], int k, int len) {
    int dad = k; // 父节点的索引
    int son = 2 * dad + 1; // 左子节点的索引
    
    // 当子节点在数组范围内时进行调整
    while (son < len) {
        // 如果右子节点存在并且比左子节点大,则定位到右子节点
        if (son + 1 < len && A[son] < A[son + 1]) {
            son++;
        }
        
        // 如果子节点大于父节点,则交换它们
        if (A[son] > A[dad]) {
            swap(A[son], A[dad]);
            dad = son; // 更新父节点索引
            son = 2 * dad + 1; // 更新子节点索引
        } else {
            break; // 子节点不大于父节点时,停止调整
        }
    }
}

// 堆排序函数
void HeapSort(ElemType *A, int len) {
    int i;
    
    // 构建初始最大堆
    for (i = len / 2 - 1; i >= 0; i--) {
        AdjustDown(A, i, len); // 从最后一个非叶子节点开始向下调整
    }
    
    // 排序过程
    swap(A[0], A[len - 1]); // 交换最大元素到正确的位置(数组末尾)
    
    // 重复调整堆并将当前最大元素移到已排序区域
    for (i = len - 1; i > 1; i--) {
        AdjustDown(A, 0, i); // 重新调整堆,不包括已排序的元素
        swap(A[0], A[i - 1]); // 交换最大元素到正确的位置
    }
}

int main(){
    SSTable ST;
    STInit(ST,10);              // 初始化静态表,设置长度为10
    //ElemType A[10]={3,87,2,93,78,56,61,38,12,40};
    //memcpy(ST.elem,A,sizeof(A));
    STPrint(ST);                // 打印未排序的静态表
    HeapSort(ST.elem,10);     // 调用堆排序函数,对静态表中的数据进行排序
    STPrint(ST);                // 再次打印静态表,这次是排序后的结果
    scanf("%d");                // 防止程序立即退出
    return 0;
}


http://www.mrgr.cn/news/62226.html

相关文章:

  • Matlab学习03-符号的替换及运算(接上一篇)
  • 大数据新视界 -- 大数据大厂之优化大数据计算框架 Tez 的实践指南
  • MySQL安装配置教程
  • 使用TimeShift备份和恢复Ubuntu Linux
  • 没有对象来和我手撕红黑树吧
  • IEEE二区TOP!IF=5.1连年攀升,主编慧眼识珠,大修不拒
  • Redis 线程控制 问题
  • C语言实现选择排序
  • 主成分分析(PCA)在医学数据分析中的神奇力量
  • 当AI取代真相,大模型如何一步步诱骗了人类的文明?
  • ubuntu增加swap交换空间
  • 车载中控系统的UI自动化测试实践
  • VB.NET中如何利用Windows Forms进行桌面应用开发
  • HCIP-HarmonyOS Application Developer V1.0 笔记(二)
  • 代码编辑器 | Visual Studio Code v1.95.0
  • C语言:动态内存管理【上】
  • leetcode hot100【LeetCode 118. 杨辉三角】java实现
  • 二十二、MySQL 8.0 主从复制原理分析与实战
  • Kylin Server V10 下编译安装 Python
  • npm ERR! path /Users/*/Desktop/task_work_all/node_modules/canvas
  • 【动态规划之斐波那契数列模型】——累加递推型动态规划
  • Java Condition 源码
  • Java避坑案例 - “激进”的线程池扩容策略及实现
  • 串口电路设计
  • 3216. 交换后字典序最小的字符串
  • 时间序列分类任务---tsfresh库