首页 > 编程语言 >C/C++ 数据结构堆结构算法的实现

C/C++ 数据结构堆结构算法的实现

时间:2023-03-04 19:45:23浏览次数:31  
标签:index arr int C++ 算法 heap 数据结构 节点 size

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//堆的算法实现
#define DEFAULT_CAPCITY 128
typedef struct _Heap {
    int* arr; //存储堆元素的数组
    int size; //当前已存储的元素个数
    int capacity; //当前存储的容量
}Heap;
bool initHeap(Heap& heap, int* orginal, int size);
bool insert(Heap& heap, int value);
static void buildHeap(Heap& heap);
static void adjustDown(Heap& heap, int index);
static void adjustUp(Heap& heap, int index);
/*初始化堆*/
bool initHeap(Heap& heap, int* orginal, int size) {
    int capacity = DEFAULT_CAPCITY > size ? DEFAULT_CAPCITY : size;
    heap.arr = new int[capacity];
    if (!heap.arr) return false;
    heap.capacity = capacity;
    heap.size = 0;
    //如果存在原始数据则构建堆
    if (size > 0) {
        /*方式一: 直接调整所有元素
        memcpy(heap.arr, orginal, size*sizeof(int));
        heap.size = size;
        //建堆
        buildHeap(heap);
        */
        //方式二: 一次插入一个
        for (int i = 0; i < size; i++) {
            insert(heap, orginal[i]);
        }
    }
    return true;
}
/* 从最后一个父节点(size/2-1 的位置)逐个往前调整所有父节点(直到根节
点),确保每一个父节点都是一个最大堆,最后整体上形成一个最大堆 */
void buildHeap(Heap& heap) {
    int i;
    for (i = heap.size / 2 - 1; i >= 0; i--) {
        adjustDown(heap, i);
    }
}
/*将当前的节点和子节点调整成最大堆*/
void adjustDown(Heap& heap, int index)
{
    int cur = heap.arr[index];//当前待调整的节点
    int parent, child;
    /*判断是否存在大于当前节点子节点,如果不存在,则堆本身是平衡的,不
    需要调整;
    如果存在,则将最大的子节点与之交换,交换后,如果这个子节点还有子节
    点,则要继续
    按照同样的步骤对这个子节点进行调整
    */
    for (parent = index; (parent * 2 + 1) < heap.size; parent = child) {
        child = parent * 2 + 1;
        //取两个子节点中的最大的节点
        if (((child + 1) < heap.size) && (heap.arr[child] < heap.arr[child +
            1])) {
            child++;
        }
        //判断最大的节点是否大于当前的父节点
        if (cur >= heap.arr[child]) {//不大于,则不需要调整,跳出循环
            break;
        }
        else {//大于当前的父节点,进行交换,然后从子节点位置继续向下调整
            heap.arr[parent] = heap.arr[child];
            heap.arr[child] = cur;
        }
    }
}
/*将当前的节点和父节点调整成最大堆*/
void adjustUp(Heap& heap, int index) {
    if (index < 0 || index >= heap.size) {//大于堆的最大值直接 return
        return;
    }
    while (index > 0) {
        int temp = heap.arr[index];
        int parent = (index - 1) / 2;
        if (parent >= 0) {//如果索引没有出界就执行想要的操作
            if (temp > heap.arr[parent]) {
                heap.arr[index] = heap.arr[parent];
                heap.arr[parent] = temp;
                index = parent;
            }
            else {//如果已经比父亲小 直接结束循环
                break;
            }
        }
        else {//越界结束循环
            break;
        }
    }
}
/*最大堆尾部插入节点,同时保证最大堆的特性*/
bool insert(Heap& heap, int value) {
    if (heap.size == heap.capacity) {
        fprintf(stderr, "栈空间耗尽!\n");
        return false;
    }
    int index = heap.size;
    heap.arr[heap.size++] = value;
    adjustUp(heap, index);
    return true;
}
int main(void) {
    Heap hp;
    int origVals[] = { 1, 2, 3, 87, 93, 82, 92, 86, 95 };
    int i = 0;
    if (!initHeap(hp, origVals, sizeof(origVals) / sizeof(origVals[0]))) {
        fprintf(stderr, "初始化堆失败!\n");
        exit(-1);
    }
    for (i = 0; i < hp.size; i++) {
        printf("the %dth element:%d\n", i, hp.arr[i]);
    }
    insert(hp, 99);
    printf("在堆中插入新的元素 99,插入结果:\n");
    for (i = 0; i < hp.size; i++) {
        printf("the %dth element:%d\n", i, hp.arr[i]);
    }
    system("pause");
    return 0;
}

标签:index,arr,int,C++,算法,heap,数据结构,节点,size
From: https://www.cnblogs.com/smartlearn/p/17178931.html

相关文章

  • m基于RFID和DBSCAN聚类的InSAR室内三维定位算法的matlab仿真
    1.算法描述       许多室内应用需要有关物体的空间信息。示例应用程序包括项目查找,对象级别映射和在仓库或库中管理的大型对象。然而,使用802.11,可见光或声学的基于......
  • m基于kmeans和SVM的网络入侵数据分类算法matlab仿真
    1.算法描述首先计算整个数据集合的平均值点,作为第一个初始聚类中心C1;然后分别计算所有对象到C1的欧式距离d,并且计算每个对象在半径R的范围内包含的对象个数W。此......
  • m基于RFID和DBSCAN聚类的InSAR室内三维定位算法的matlab仿真
    1.算法描述许多室内应用需要有关物体的空间信息。示例应用程序包括项目查找,对象级别映射和在仓库或库中管理的大型对象。然而,使用802.11,可见光或声学的基于位置的服务的传......
  • m基于隐马尔科夫模型(HMM)的手机用户行为预测(MMUB)算法matlab仿真
    1.算法描述隐马尔可夫模型(HiddenMarkovModel,HMM)是一种统计模型,广泛应用在语音识别,词性自动标注,音字转换,概率文法等各个自然语言处理等应用领域。经过长期发展,尤其是在语......
  • m基于kmeans和SVM的网络入侵数据分类算法matlab仿真
    1.算法描述       首先计算整个数据集合的平均值点,作为第一个初始聚类中心C1;        然后分别计算所有对象到C1的欧式距离d,并且计算每个对象在半径R的范......
  • 算法基础1.4.2差分
    前言学习差分前一定要先学习前缀和,因为差分就是前缀和的一个逆运算(有点像微分和积分),所以只有先搞清楚前缀和才能明白差分点这里补习前缀和这里同样也是从一维和二维两个......
  • 手刷算法day1(2)(go语言实践)
    344. 反转字符串 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使......
  • 图论基本算法
    1、深度优先遍历(DFS)  2、广度优先遍历(BFS) 3、0-1BFS --(2290.到达角落需要移除障碍物的最小数目)classSolution:defminimumObstacles(self,grid:List......
  • 手刷算法day1(1)(go语言实践)
    29.DivideTwoIntegers 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从0开始)。如果 needle......
  • 5. 决策树算法原理以及ID3算法代码实现
    完整的实验代码在我的github上......