C语言 深入解读数据结构之堆的实现

堆的概念与结构

概念:如果有一个关键码的集合K={ k0,k1 ,k2 ,…,kn-1 },把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足K i<=K 2*i+1且Ki<=K 2*i+2(K i>=K 2*i+1且Ki>=K 2*i+2) i = 0,1,2...,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。

结构:

1.大堆

2.小堆

堆(大根堆)的实现:

堆的接口:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int HPDataType;
typedef struct Heap
{
    HPDataType* a;
    int size;
    int capacity;
}HP;

//堆的创建
void HeapInit(HP*hp);
//堆的销毁
void HeapDestroy(HP*hp);
//交换数值
void Swap(HPDataType *px, HPDataType *py);
//向上调整
void AdjustUp(int *a,int child);
//向下调整
void AdjustDown(int *a, int n, int parent);
//堆的插入
void HeapPush(HP*hp,HPDataType x);
//堆的删除
void HeapPop(HP*hp);
//取堆顶的数据
HPDataType HeapTop(HP*hp);
//打印堆
void HeapPrint(HP*hp);
//堆的判空
bool HeapEmpty(HP*hp);
//堆的数据个数
int HeapSize(HP*hp);

堆的创建:

void HeapInit(HP*hp)
{
    assert(hp);
    hp->a=NULL;
    hp->capacity=hp->size=0;
}

堆的销毁:

void HeapDestroy(HP*hp)
{
    assert(hp);
    free(hp->a);
    hp->capacity=hp->size=0;
}

交换数值:

void Swap(HPDataType*px, HPDataType*py)
{
    HPDataType tmp = *px;
    *px=*py;
    *py=tmp;
}

向上调整:

void AdjustUp(int*a, int child)
{
	assert(a);
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
            //交换数值
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

堆得插入:

void HeapPush(HP*hp,HPDataType x)
{
    assert(hp);
    if(hp->capacity==hp->size)
    {
        size_t newCapacity=hp->capacity==0?4:hp->capacity*2;
        HPDataType * tmp=(HPDataType*)realloc(hp->a,newCapacity*sizeof(HPDataType));
        if(tmp==NULL)
        {
            printf("realloc is fail\n");
        }
        hp->a=tmp;
        hp->capacity=newCapacity;

    }
    hp->a[hp->size-1]=x;
    hp->size++;
    //向上调整
    AdjusiUp(hp->a,hp->size-1);
}

向下调整:

void AdjustDown(int *a,int n,int parent)
{
    int child=parent*2+1;
    while(child<n)
    {
        //比较左孩子还是右孩子大
        if(child+1<n && a[child+1]>a[child])
        {
            child++;
        }
        if(a[child]>a[parent])
        {
            Swap(&a[child],&a[parent]);
            parent=child;
            child=parent*2+1;
        }
        else
        {
            break;
        }
    }
}

堆的判空:

bool HeapEmpty(HP*hp)
{
    assert(hp);
    return hp->size==0;
}

堆的删除:

void HeapPop(HP*hp)
{
	assert(hp);
    //堆的判空
	assert(!HeapEmpty(hp));
    //交换数值
	Swap(&hp->a[0], &hp->a[hp->size - 1]);
	hp->size--;
    //向下调整
	AdjustDown(hp->a, hp->size, 0);
}

取堆顶的数据:

HPDataType HeapTop(HP*hp)
{
    assert(hp);
    assert(!HeapEmpty(hp));
    return hp->a[0];
}

打印堆:

void HeapPrint(HP*hp)
{
    assert(hp);
    assert(!HeapEmpty(hp));
    for(int i=0; i<hp->size;i++)
    {
        printf("%d",hp->a[i]);
    }
    printf("\n");
}

堆的数据个数:

int HeapSize(HP*hp)
{
    assert(hp);
    return hp->size;
}

以上就是对堆的讲解与操作实现。

感谢老铁看到这里,如果文章对你有用的话请给我一个赞支持一下,感激不尽!

在下才疏学浅,一点浅薄之见,欢迎各位大佬指点。

以上就是C语言 深入解读数据结构之堆的实现的详细内容,更多关于C语言 数据结构的资料请关注我们其它相关文章!

(0)

相关推荐

  • 深入浅析C语言中堆栈和队列

    1.堆和栈 (1)数据结构的堆和栈 堆栈是两种数据结构. 栈(栈像装数据的桶或箱子):是一种具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取.这就如同要取出放在箱子里面底下的东西(放入的比较早的物体),首先要移开压在它上面的物体(放入的比较晚的物体). 堆(堆像一棵倒过来的树):是一种经过排序的树形数据结构,每个结点都有一个值.通常所说的堆的数据结构,是指二叉堆.堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆.由于堆的这个特性,常用来实现优先队列,堆的存取是随意,

  • C语言实现数据结构串(堆分配存储表示法)实例详解

    堆分配存储表示法 存储结构: 构建堆来存储字符串,本质上是顺序表 实现代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 #define STR_INIT_SIZE 100 #define STRINCREMENT 10 typedef i

  • C语言 数据结构堆排序顺序存储(升序)

    堆排序顺序存储(升序) 一: 完全二叉树的概念:前h-1层为满二叉树,最后一层连续缺失右结点! 二:首先堆是一棵全完二叉树: a:构建一个堆分为两步:⑴创建一棵完全二叉树      ⑵调整为一个堆 (标注:大根堆为升序,小根堆为降序) b:算法描述:①创建一棵完全二叉树 ②while(有双亲){ A:调整为大根堆: B:交换根和叶子结点: C:砍掉叶子结点: } c:时间复杂度为 O(nlogn)  ,空间复杂度为 O(1), 是不稳定排序! 代码实现: /*堆排序思想:[完全二叉树的定义:前

  • 浅析C语言中堆和栈的区别

    在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到.但对于很多的初学着来说,堆栈是一个很模糊的概念. 堆栈:一种数据结构.一个在程序运行时用于存放的地方,这可能是很多初学者的认识,因为我曾经就是这么想的和汇编语言中的堆栈一词混为一谈.我身边的一些编程的朋友以及在网上看帖遇到的朋友中有好多也说不清堆栈,所以我想有必要给大家分享一下我对堆栈的看法,有说的不对的地方请朋友们不吝赐教,这对于大家学习会有很大帮助. 一.前言: C语言程序经过编译连接后形成编译.连接后形成的二进制映

  • C语言数据结构之堆排序源代码

    本文实例为大家分享了C语言堆排序源代码,供大家参考,具体内容如下 1. 堆排序 堆排序的定义及思想可以参考百度百科: 用一句概括,堆排序就是一种改进的选择排序,改进的地方在于,每次做选择的时候,不单单把最大的数字选择出来,而且把排序过程中的一些操作进行了记录,这样在后续排序中可以利用,并且有分组的思想在里面,从而提高了排序效率,其效率为O(n*logn). 2. 源代码 堆排序中有两个核心的操作,一个是创建大顶堆(或者小顶堆,这里用的是大顶堆),再一个就是对堆进行调整.这里需要注意的是,并没有真

  • C语言二叉树与堆的概念与实现

    目录 引言-树的故事 树的基本性质和描述 树的基本特点 树的关键字解析 树的表示方法 二叉树的概念结构 特殊二叉树 二叉树的性质 二叉树的存储结构 二叉树与堆 堆的实现 堆排序 堆的功能实现 TOPK问题 二叉树的结构以及实现 二叉树的遍历 总结 引言-树的故事 在自然界中有很多树 它们是这样的 但是在我们的眼中 他是这样的 显而易见 树的特点就是一对多 ,我们利用这个一对多的特点,可以让我们更好的解决编程中的问题,在树中 ,最基础的二叉树是我们的重点研究对象. 在看一眼神奇的堆排序的动态图 做

  • C语言 深入解读数据结构之堆的实现

    堆的概念与结构 概念:如果有一个关键码的集合K={ k0,k1 ,k2 ,-,kn-1 },把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足K i<=K 2*i+1且Ki<=K 2*i+2(K i>=K 2*i+1且Ki>=K 2*i+2) i = 0,1,2...,则称为小堆(或大堆).将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆. 性质: 堆中某个节点的值总是不大于或不小于其父节点的值: 堆总是一棵完全二叉树. 结构: 1.大堆 2

  • C语言植物大战数据结构二叉树堆

    目录 前言 堆的概念 创建结构体 初始化结构体 销毁结构体 向堆中插入数据 1.堆的物理结构和逻辑结构 2.完全二叉树下标规律 3.插入数据思路 依次打印堆的值 删除堆顶的值 判断堆是否为空 求堆中有几个元素 得到堆顶的值 堆排序 总体代码 Heap.h Heap.c Test.c “竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生” C语言朱武大战数据结构专栏 C语言植物大战数据结构快速排序图文示例 C语言植物大战数据结构希尔排序算法 C语言植物大战数据结构堆排序图文示例 C语言植物大战数据结构二叉树递归

  • C语言数据结构之堆、堆排序的分析及实现

    目录 1.堆的概念结构及分类 1.2堆的分类 1.2.1 大堆 1.2.2 小堆 2. 堆的主要接口 3.堆的实现 3.1 堆的初始化 HeapInit 3.2 堆的销毁 HeapDestory 3.3 堆的打印 HeapPrint 3.4 堆的插入元素 HeapPush   * 3.5 堆的删除元素 HeapPop  * 4.堆的应用:堆排序   *** 4.1 堆排序实现过程分析 4.3 堆排序结果演示 5.堆(小堆)的完整代码 总结  1.堆的概念结构及分类 以上这段概念描述看起来十分复杂

  • Java 精炼解读数据结构逻辑控制

    目录 一.顺序结构 二.分支结构 switch语句  三.循环结构 3.1while循环  3.2break 3.3continue  3.4for循环  3.5dowhile循环(选学)  总结: 一.顺序结构 程序的执行和代码的执行顺序有关,如果调整代码的书写顺序, 则执行顺序也发生变化 二.分支结构 基本语法形式1: if(布尔表达式){     //条件满足时执行代码 } 基本语法形式2 if(布尔表达式){     //条件满足时执行代码 }else{     //条件不满足时执行代码

  • C语言详解如何实现堆及堆的结构与接口

    目录 一.堆的结构及实现(重要) 1.1 二叉树的顺序结构 1.2 堆的概念及结构 1.3 堆的实现 1.3.1 堆的向下调整算法 1.3.2 向下调整算法的时间复杂度 1.3.3 堆的创建(向下调整) 1.3.4 堆排序 1.3.5 建堆的时间复杂度 二.堆的相关接口实现(以大堆为例) 2.1 堆的初始化 2.2 堆的销毁 2.3 堆的插入 2.4 堆的删除 2.5 获取堆顶元素 2.6 堆的判空 2.7 找出堆中前k个最大元素 2.8 堆的创建(向上调整) 一.堆的结构及实现(重要) 1.1

  • C语言植物大战数据结构堆排序图文示例

    目录 TOP.堆排序前言 一.向下调整堆排序 1.向下调整建堆 建堆的技巧 建堆思路代码 2.向下调整排序 调整思路 排序整体代码 3.时间复杂度(难点) 向下建堆O(N) 向下调整(N*LogN) 二.向上调整堆排序 1.向上调整建堆 2.建堆代码 “大弦嘈嘈如急雨,小弦切切如私语”“嘈嘈切切错杂弹,大珠小珠落玉盘” TOP.堆排序前言 什么是堆排序?假如给你下面的代码让你完善堆排序,你会怎么写?你会怎么排? void HeapSort(int* a, int n) { } int main(

  • Java 数据结构之堆的概念与应用

    目录 什么是堆 堆的类型 小根堆 大根堆 堆的基本操作:创建堆 堆的时间复杂度和空间复杂度 堆的应用-优先级队列 概念 优先级队列基本操作 入优先级队列 出优先级队列首元素 java的优先级队列 堆的常见面试题 最后一块石头的重量 找到K个最接近的元素 查找和最小的K对数字 java数据结构的堆 什么是堆 堆指的是使用数组保存完全二叉树结构,以层次遍历的方式放入数组中. 如图: 注意:堆方式适合于完全二叉树,对于非完全二叉树若使用堆则会造成空间的浪费 对于根节点与其左右孩子在数组中的下标关系可表

  • C语言实现通用数据结构之通用椎栈

    本文实例为大家分享了C语言实现通用数据结构之通用椎栈的具体代码,供大家参考,具体内容如下 这是在通用链表的基础上实现的椎栈,关于链表的实现参见:C语言实现通用数据结构之通用链表 . 这里所说的椎栈就是指的栈. 注意椎栈中只存储了指针,没有储存实际的数据. 头文件: /************************* *** File myStack.h **************************/ #ifndef MYSTACK_H_INCLUDED #define MYSTACK_

  • C语言实现通用数据结构之通用集合(HashSet)

    这是在通用链表的基础上实现的集合,关于链表的实现参见:C语言实现通用数据结构之通用链表 注意集合中只存储了指针,没有储存实际的数据. 对于新的数据类型来说,需要自定义HashCode函数和equal函数. 下面还给出了几个常见的hashCode函数和equal函数. (1)HashCode函数 头文件 /************************* *** File myHashCode.h **************************/ #ifndef MYHASHCODE_H_

  • C语言实现通用数据结构之通用链表

    本文实例为大家分享了c语言实现通用数据结构之通用链表的具体代码,供大家参考,具体内容如下 忽然想起来,大概在两年之前学习C语言的时候,曾经用C语言写过一些通用的数据结构.主要也就实现了链表.队列.椎.HashSet,还有HashMap.当时只是知道标准的C语言中没有这方面的类库,后来才知道有很多第三方的类似这样的类库.废话不多说,先把代码粘过来. 下面实现的是通用链表,注意链表中只存储了指针,没有储存实际的数据. 头文件 /************************* *** File m

随机推荐