Array Implementation of min-Heaps 最小堆数组实现

一、实验名称:Array Implementation of min-Heaps

二、实验目的:
4. 熟练掌握最小堆的数据结构,结构的特点;
5. 能够实现最小堆的基本操作:如构造,插入,删除,初始化,回收内存等
三、实验内容:

A complete min-heap is a min-heap with the structure of a complete binary tree which can be stored using an array.

  1. Determine the array structures for a complete min-heap(以数组形式表示的树结构)
  2. Input a linear list of 20 random numbers, building a complete min-heap to store the numbers
  3. Implement POP and PUSH operations for the min-heaps.

四. 算法实现:
通过在堆的末尾添加或删除,插入和删除操作都首先修改堆以使其符合shape属性。然后,通过向上或向下遍历堆来恢复堆属性。两种操作都需要O(log n)时间。
1.插入
要将元素添加到堆,我们可以执行以下算法:

将元素添加到堆的最底层开放空间的最底层。
将添加的元素与其父元素进行比较;如果顺序正确,请停止。
如果不是,则将元素与其父元素交换并返回上一步。
步骤2和3通过比较节点并可能与其父节点交换节点来恢复堆属性,这些步骤称为up-heap操作。

所需的操作数仅取决于新元素必须满足堆属性的级别数。因此,插入操作的最坏情况时间复杂度为O(log n)。对于随机堆和重复插入,插入操作的平均情况复杂度为O(1)。
2.弹出
从堆中删除根的过程(有效地提取max-heap中的最大元素或min-heap中的最小元素),同时保留heap属性:

用最后一级的最后一个元素替换堆的根。
将新的根与其子代进行比较;如果顺序正确,请停止。
如果不是,则将元素与其子元素之一交换并返回上一步。(将其较小的子项换成最小堆,将其较大的子项换成最大堆。)
步骤2和3通过将节点与子节点之一进行比较并可能与其交换来恢复堆属性,这些步骤称为下降堆操作

3.建立堆
从最低级别开始向上移动,像删除算法一样向下筛选每个子树的根,直到恢复堆属性。

四. 程序清单(较为详细的注释):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MaxSize 100
typedef struct Hnode* MinHeap;
struct Hnode{
    int* data;
    int size;
    int Capacity;
};
int getRandomNum(){
    int RandomNum;
    RandomNum=rand();
    return  RandomNum;
}
/*Filter down and find the proper position of the node on the premise that all subtrees are the smallest heap. 
The tree with this node as the root node is a smallest heap*/
void FixDown(MinHeap h,int index){
    int parent;
    int child;
    int temp=h->data[index];
    for(parent=index;parent*2<=h->size;parent=child){
        child=parent*2;
        if(child+1<=h->size&&h->data[child+1]<h->data[child])
            child++;
        if(h->data[child]<temp){
            h->data[parent]=h->data[child];
        }
        else break;
    }
    h->data[parent]=temp;
}
/*The idea of recursion is adopted to establish the minimum heap from bottom to top, which ensures 
that the subtrees currently established are all the smallest heaps.*/
void BuildMinHeap(MinHeap h){
    int i;
    for(i=h->size/2;i>=1;i--){
        FixDown(h,i);
    }
}
//Determine whether the MinHeap is empty
int Empty(MinHeap h){
    return h->size==0;
}
//Return and delete the minimum value of the minimum heap (that is, the head node), and keep the tree as the minimum heap
/*Move the last node to the head node, and size--,
Because the subtrees are all the smallest heap at this time, filtering directly 
down can ensure that the tree is still the smallest heap*/
int PopMinHeap(MinHeap h){
    if(Empty(h)){
        printf("The minimum heap is empty, and the popped -11111 is an invalid value\n");
        return -11111;
    }
    int result=h->data[1];
    h->data[1]=h->data[(h->size)--];
    //向下过滤
    FixDown(h,1);
    return result;
}
/*Insert node, keep minimum heap*/
void PushMinHeap(MinHeap h,int val){
    if(h->size==h->Capacity){
        printf("The minimum heap is full and element insertion is invalid\n");
        return;
    }
    h->data[++(h->size)]=val;
    //向上过滤
    int child=h->size;
    int parent;
    for(;child>1;child=parent){
        parent=child/2;
        if(h->data[parent]>val){
            h->data[child]=h->data[parent];
        }
        else
        {
            break;
        }
        
    }
    h->data[child]=val;
}
/*Request space for the MinHeap*/
MinHeap CreateMinHeap(int MinHeapSize){
    MinHeap h=(MinHeap)malloc(sizeof(MinHeap));
    h->data=(int*)malloc((MinHeapSize+1)*sizeof(int));
    h->size=0;
    h->Capacity=MinHeapSize;
    return h;
}
/*Free up space for MinHeap*/
void CleanMinHeap(MinHeap h){
    free(h->data);
    free(h);
}
int main()
{
    MinHeap h=CreateMinHeap(MaxSize);

    //Construct the MinHeap with a random array of 20 numbers, and pop the MinHeap number in turn
    printf("Construct the MinHeap with a random array of 20 numbers\n");
    srand((unsigned)time(NULL));
    int i=1;
    printf("20 random numbers:\n");
    for(;i<=20;i++){
        h->data[i]=getRandomNum();
        printf("%d ",h->data[i]);
        h->size++;
    }
     printf("\n");
    BuildMinHeap(h);
    //After the minimum heap is established, pop the element
    printf("After the minimum heap is established, pop the element:\n");
    while(!Empty(h)){
        printf("%d ",PopMinHeap(h));
    }
     printf("\n");


    //Randomly insert 10 elements
    int randNum;
    printf("10 random numbers inserted in sequence:\n");
    for(i=1;i<=10;i++){
        randNum=getRandomNum();
        printf("%d ",randNum);
        PushMinHeap(h,randNum);
    }
    printf("\n");
    //while the minimum heap is not empty, pop the element
    printf("After the insertion, pop the element:\n");
    while(!Empty(h)){
        printf("%d ",PopMinHeap(h));
    }
     printf("\n");
    CleanMinHeap(h);
    return 0;
}

五、测试结果:

输入输出格式说明:

  • 输入格式:

  • 输出格式:
    先输出20个随机数组的内容;
    再输出数组构造的最小堆,依次弹出的内容;
    再输出10个依次插入的随机;
    再依次插入后的最小堆,依次弹出的内容;

  • 测试样例1:

    输入:

    输出:

    Construct the MinHeap with a random array of 20 numbers
    20 random numbers:
    25934 30979 23498 31152 11647 2301 29550 22606 11334 6914 30615 28013 5979 11444 21228 3691 28332 32284 17894 14376
    After the minimum heap is established, pop the element:
    2301 3691 5979 6914 11334 11444 11647 14376 17894 21228 22606 23498 25934 28013 28332 29550 30615 30979 31152 32284
    10 random numbers inserted in sequence:
    16559 5286 28109 18979 2294 28525 14307 31967 23812 20665
    After the insertion, pop the element:
    2294 5286 14307 16559 18979 20665 23812 28109 28525 31967
    
  • 测试样例2:

    输入:

    输出:

    Construct the MinHeap with a random array of 20 numbers
    20 random numbers:
    26012 26797 26254 18847 29821 31007 5944 17888 14396 23200 27065 29070 13024 15340 29552 26589 16604 15737 29064 21912
    After the minimum heap is established, pop the element:
    5944 13024 14396 15340 15737 16604 17888 18847 21912 23200 26012 26254 26589 26797 27065 29064 29070 29552 29821 31007
    10 random numbers inserted in sequence:
    28387 16381 28017 23489 25085 31792 1424 1400 1499 18387
    After the insertion, pop the element:
    1400 1424 1499 16381 18387 23489 25085 28017 28387 31792
    
    
  • 测试样例3:

    输入:

    输出:

    Construct the MinHeap with a random array of 20 numbers
    20 random numbers:
    26058 13435 14208 28054 10385 20445 16751 9674 16182 2663 24995 29686 28056 17613 12562 7179 31608 11546 21926 23578       
    After the minimum heap is established, pop the element:
    2663 7179 9674 10385 11546 12562 13435 14208 16182 16751 17613 20445 21926 23578 24995 26058 28054 28056 29686 31608       
    10 random numbers inserted in sequence:
    24364 3738 8848 23389 151 22775 4832 2683 10328 8866
    After the insertion, pop the element:
    151 2683 3738 4832 8848 8866 10328 22775 23389 24364
    
  • 测试样例4:

    输入:

    	
    

    输出:

    Construct the MinHeap with a random array of 20 numbers
    20 random numbers:
    26133 31272 31868 24454 18244 12456 22801 7883 2733 25098 21593 30699 12962 4962 31462 12739 25829 9342 31264 7589
    After the minimum heap is established, pop the element:
    2733 4962 7589 7883 9342 12456 12739 12962 18244 21593 22801 24454 25098 25829 26133 30699 31264 31272 31462 31868
    10 random numbers inserted in sequence:
    24777 32119 26509 20885 8339 14983 3408 21176 10790 18970
    After the insertion, pop the element:
    3408 8339 10790 14983 18970 20885 21176 24777 26509 32119
    
    

六、算法分析:
最小堆的插入和删除操作都是在树的结构基础上建立的,每次的时间复杂度为O(log n)时间,
若算法需要n次插入,每次删除,则插入和删除总共的时间复杂度为O((n+m)log n);
构造有n个节点的最小堆,同理其时间复杂度为O(nlog n);
算法的空间复杂度为最小堆数据结构(以数组形式表示的树结构)的内存空间

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值