数据结构 二叉堆 数组实现

本文介绍了数据结构中的二叉堆,特别是通过数组实现二叉堆的方法。二叉堆具有非叶子节点值不大于(或不小于)其左右孩子值的性质。在数组上实现堆可以方便地进行节点比较。堆操作包括插入元素和取出元素,其中插入时要保持堆性质,取出元素通常取最大或最小值,可通过大顶堆和小顶堆实现。详细步骤以小顶堆为例进行了说明。

堆还是比较常用的数据结构

二叉堆也就是以二叉树形式构造的堆

我们知道二叉树可以用数组很方便的实现

所以用数组实现二叉堆也不是很难的事情

首先我们来了解一下二叉堆的性质:非叶子节点的值均不大于(或不小于)其左右孩子的值

如果用二叉堆用数组来实现就是n个元素{k1,k2,k3,...,kn}

ki<=k(2*i)&&ki<=k(2*i+1)  或者 ki>=k(2*i)&&ki>=k(2*i+1)    其中(i=1,2,...,n/2);

如此我们就能很方便的在数组上实现根节点和孩子节点的比较

堆中插入元素,插入元素之后还需要保持堆的性质

堆中取元素的时候一般都是取得堆中最大或者最小的元素

这时我们就可以使用大顶堆来维护取最大值,小顶堆来维护取最小值

堆中取出元素时也需要继续维护堆的性质


以小顶堆的数组 实现为例

插入元素:

1.从堆末尾插入元素

2.比较和其父节点元素的大小

    2.1.比父节点小,对元素和父节点的元素执行交换操作,

    2.2.比父节点大,结束

3.重复2直到根节点


取出最小元素:

1.取出堆的根节点

2.取出堆的最后一个元素插入到根节点

3.比较根节点和左右孩子的大小

   3.1.比左右孩子都大,结束

   3.2.只比一个大,交换根节点元素和孩子节点元素

   3.3.比两个都大,和最小的那个孩子节点交换

4.重复3直到结束,返回1取出的根节点


下面实现一个小顶堆来维护取最小值。

#include<stdlib.h>
#include<stdio.h>
int heap[1000];//定义堆的大小
int end=0;//指向堆中的最后一个元素并且标记元素的个数

void insert(int a){
    int e,p,tmp;//e最后一个元素在数组的位置,p为e的父节点。
    heap[++end]=a;//从尾部插入元素
    e=end;
    //对插入的元素进行上升操作
    while(e>1){
        p=e>>1;
        if(heap[e]<heap[p]){//如果比父节点小就上升
            tmp=heap[e];
            heap[e]=heap[p];
            heap[p]=tmp;
        }else break;//比父节点大直接break,小顶堆的性质决定
        e=p;
    }
}
int getMin(){

    int ls,rs,rt=1;            //rt指向堆的根节点,ls指向根节点的左孩子,rs指向根节点的右孩子
    int res,last,tmp;       //res堆中的最小值,也就是堆的根节点,last为堆中的最后一个元素
    res=heap[rt];           //取出根节点,所以堆的元素个数需要减一
    last=heap[end--];    //得到堆的最后一个元素
    heap[rt]=last;          //把最后一个元素从根节点插入

    //对根节点进行下降操作
    while(1){
        ls=rt<<1;rs=rt<<1|1;

        if(ls>end||rs>end){//如果左孩子或者右孩子指向超出元素的总数,也就是指向空
            if(ls<=end&&heap[rt]>heap[ls]){//左孩子没有超出,并且需要交换
                tmp=heap[rt];
                heap[rt]=heap[ls];
                heap[ls]=tmp;
            }
            break;
        }

        if(heap[rt]<=heap[ls]&&heap[rt]<=heap[rs])break;//左孩子右孩子都比根节点大,不需要交换

        if(heap[rt]>heap[ls]&&heap[rs]>=heap[ls]){//比较根节点和左右孩子,和最小的交换
            tmp=heap[rt];
            heap[rt]=heap[ls];
            heap[ls]=tmp;
            rt=ls;
        }else{
            tmp=heap[rt];
            heap[rt]=heap[rs];
            heap[rs]=tmp;
            rt=rs;
        }

    }
    return res;
}
int main(){
    //插入20个数据进行测试一下
    int a,i;
    for(i=1;i<=20;i++){
        a=rand()%100;
        printf("%2d ",a);
        insert(a);
    }
    printf("\n");
    while(end>0){
      printf("%2d ",getMin());
    }
    printf("\n");
return 0;
}

数据结构中的二叉数组,也称为位数组(Bit Array),是一种特殊的数据结构,用于高效地表示和操作一组离散的状态,每个状态通常代表一个二进制位(0或1)。创建一个二叉数组的主要函数,通常包含以下几个步骤: 1. **初始化**:确定数组的大小,比如`size`,因为二叉数组通常用整数索引来访问元素,所以需要知道最大的可能索引。 ```c++ int *binaryArray = new int[size]; // 创建一个整型数组,每个元素对应一位 ``` 2. **创建**:对于数组的每个元素,你可以将其初始化为0,这表示默认的未分配状态。 ```c++ for (int i = 0; i < size; i++) { binaryArray[i] = 0; } ``` 3. **访问和修改**:使用二进制位操作,如`&`(按位与)、`|`(按位或)、`~`(按位取反)等,来读取或设置特定位置的状态。例如,`binaryArray[index / sizeof(int)] & (1 << index % sizeof(int))`可以用来检查一个位置是否已设置。 4. **清理**:当不再需要数组时,别忘了释放内存。 ```c++ delete[] binaryArray; ``` 主函数示例(假设名为`createBinaryArray`): ```c++ #include <iostream> void createBinaryArray(int size) { int *binaryArray = new int[size]; for (int i = 0; i < size; i++) { binaryArray[i] = 0; std::cout << "Element at index " << i << ": " << (binaryArray[i] ? "Set" : "Unset") << "\n"; } // ... 其他操作 ... delete[] binaryArray; } int main() { int arraySize = 10; createBinaryArray(arraySize); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值