• 实现堆结构


    描述

    定义一个数组,初始化为空。在数组上执行两种操作:

    1、增添1个元素,把1个新的元素放入数组。

    2、输出并删除数组中最小的数。

    使用堆结构实现上述功能的高效算法。

    输入第一行输入一个整数t,代表测试数据的组数。
    对于每组测试数据,第一行输入一个整数n,代表操作的次数。
    每次操作首先输入一个整数type。
    当type=1,增添操作,接着输入一个整数u,代表要插入的元素。
    当type=2,输出删除操作,输出并删除数组中最小的元素。
    1<=n<=100000。输出每次删除操作输出被删除的数字。样例输入

    2
    5
    1 1
    1 2
    1 3
    2
    2
    4
    1 5
    1 1
    1 7
    2

    样例输出

    1
    2
    1
    #include<stdio.h>
    #include<stdlib.h>
    typedef int ElemType;
    struct HeapSq //定义堆的顺序存储类型
    {
        ElemType* heap; //定义指向动态数组空间的指针
        int len; //定义保存堆长度的变量,即数组长度,数组下标从0开始
        int MaxSize;    //用于保存初始化时所给的动态数组空间的大小
    };
    
    //1、初始化堆
    void InitHeap(struct HeapSq* HBT, int MS)
    {
        if (MS <= 0)
        {
            printf("数组长度参数不合适,需重新给定!
    ");
            exit(1);
        }
        HBT->heap = malloc(MS*sizeof(ElemType));
        if (!HBT->heap)
        {
            printf("用于动态分配的内存空间用完,退出运行!
    ");
            exit(1);
        }
        HBT->MaxSize = MS;
        HBT->len = 0;
    }
    
    //2、清除堆
    void ClearHeap(struct HeapSq* HBT)
    {
        if (HBT->heap != NULL)
        {
            free(HBT->heap);
            HBT->len = 0;
            HBT->MaxSize = 0;
        }
    }
    
    //3、检查一个堆是否为空
    int EmptyHeap(struct HeapSq* HBT)
    {
        if (HBT->len == 0)
            return 1;
        else
            return 0;
    }
    
    //4、向堆中插入一个元素
    void InsertHeap(struct HeapSq* HBT, ElemType x)
    {
        int i;
        if (HBT->len == HBT->MaxSize) //若堆满,将数组空间扩展为原来的2倍
        {
            ElemType *p;
            p = realloc(HBT->heap, 2*HBT->MaxSize*sizeof(ElemType));
            if (!p)
            {
                printf("存储空间用完!
    ");
                exit(1);
            }
            printf("存储空间已扩展为原来的2倍!
    ");
            HBT->heap = p;
            HBT->MaxSize = 2*HBT->MaxSize;
        }
        HBT->heap[HBT->len] = x; //向堆尾添加新元素
        HBT->len++; //堆长度加1
        i = HBT->len - 1; //i指向待调整元素的位置,即其数组下标,初始指向新元素所在的堆尾位置
        while (i != 0)
        {
            int j = (i - 1) / 2; //j指向下标为i的元素的双亲
            if (x >= HBT->heap[j]) //若新元素大于待调整元素的双亲,则比较调整结束,退出循环
                break;
            HBT->heap[i] = HBT->heap[j]; //将双亲元素下移到待调整元素的位置
            i = j; //使待调整位置变为其双亲位置,进行下一次循环
        }
        HBT->heap[i] = x;//把新元素调整到最终位置
    }
    
    //5、从堆中删除堆顶元素并返回
    ElemType DeleteHeap(struct HeapSq* HBT)
    {
        ElemType temp, x;
        int i, j;
        if (HBT->len == 0)
        {
            printf("堆已空,退出运行!
    ");
            exit(1);
        }
        temp = HBT->heap[0]; //暂存堆顶元素
        HBT->len--;
        if (HBT->len == 0) //若删除操作后堆为空则返回
            return temp;
        x = HBT->heap[HBT->len]; //将待调整的原堆尾元素暂存x中,以便放入最终位置
        i = 0; //用i指向待调整元素的位置,初始指向堆顶位置
        j = 2 * i + 1;//用j指向i的左孩子位置,初始指向下标为1的位置
        while (j <= HBT->len - 1)//寻找待调整元素的最终位置,每次使孩子元素上移一层,调整到孩子为空时止
        {
            if (j < HBT->len - 1 && HBT->heap[j] > HBT->heap[j+1])//若存在右孩子且较小,使j指向右孩子
                j++;
            if (x <= HBT->heap[j]) //若x比其较小的孩子还小,则调整结束,退出循环
                break;
            HBT->heap[i] = HBT->heap[j];//否则,将孩子元素移到双亲位置
            i = j; //将待调整位置变为其较小的孩子位置
            j = 2 * i + 1;//将j变为新的待调整位置的左孩子位置,继续下一次循环
        }
        HBT->heap[i] = x; //把x放到最终位置
        return temp; //返回原堆顶元素
    }
    
    //主函数
    int main()
    {
        int times, x, a, c,d;
        int i =0, j=0;
        scanf("%d",&times);
        //printf("%d", times);
        for(i= 0; i<times; i++){
           scanf("%d",&x);
           //printf("%d", x);
           struct HeapSq b;
           InitHeap(&b, x);
           for(j=x; j>0; j--){
              scanf("%d",&a);
              //printf("%d", a);
              if(a == 1){
                   scanf("%d",&c);
                   InsertHeap(&b, c);
              } else if(a == 2){
                   d = DeleteHeap(&b);
                   printf("%d", d);
                   printf("
    ");
              }
           }
        }
        //system("pause");
        return 0;
    }
  • 相关阅读:
    使用 ASP.NET Core 创建 Web API
    C# 请求接口返回中文乱码→???
    无法从命令行或调试器启动服务,必须首先安装Windows服务(使用installutil.exe),然后用ServerExplorer、Windows服务器管理工具或NET START命令启动它
    制作和引用自定义图标库
    asp.net core 3.1 解决跨域的问题
    看自己以前写的代码
    图解SQL Server 数据库定时自动备份
    码云修改登录密码后终端连不上的问题
    C#中string.format用法详解
    C#高级编程之泛型详解
  • 原文地址:https://www.cnblogs.com/zl0372/p/min_heap2.html
Copyright © 2020-2023  润新知