IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构——堆 -> 正文阅读

[数据结构与算法]数据结构——堆


什么是堆

把所有的元素按照完全二叉树的形式储存在一维数组中,如果该二叉树满足父节点小于等于子节点,叫做小堆;如果该二叉树满足父节点大于等于子节点,叫做大堆。

堆的实现

堆类型的创建

堆的物理结构本质上是顺序存储的,是线性的。但在逻辑上不是线性的,是完全二叉树的这种逻辑储存结构。
堆的这个数据结构,里面的成员包括一维数组,数组的容量,数组元素的个数。

typedef int HPDataType;

typedef struct heap
{
	HPDataType* arr;
	int size;
	int capacity;
}Heap;

堆的初始化

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

堆的向上调整算法和向下调整算法

向上调整算法

给我的节点当做子节点,然后找到父节点,比较父子的大小,(看你是想建小堆还是大堆),直到比到子节点到根节点就停止比较,这时就已经调整好一次了。
下面的这个例子调整成的是小堆

void swap(HPDataType* a, HPDataType* b)
{
	HPDataType c = *a;
	*a = *b;
	*b = c;
}

void adjustup(Heap* hp, int child)
{
	int father = (child - 1) / 2;
	while (child > 0)
	{
		if (hp->arr[child] < hp->arr[father])
		{
			swap(&(hp->arr[child]), &(hp->arr[father]));
			child = father;
			father = (child - 1) / 2;
		}	
		else
			break;
	}
}

向下调整算法

给我的节点当做父节点,然后找到子节点(这个节点为左孩子,我们需要找到这两个孩子中较大的或者较小的当作子节点),比较父子的大小,(看你是想建小堆还是大堆),直到比到子节点超过节点个数的时候就停止比较,这时就已经调整好一次了。

void adjustdown(Heap* hp, int father)
{
	int child = 2 * father + 1;
	while (child < hp->size)
	{
	//因为这里有child+1,所以要注意边界问题
		if (child < hp->size-1&&hp->arr[child] > hp->arr[child + 1])
			child++;
		if (hp->arr[child] < hp->arr[father])
		{
			swap(&(hp->arr[child]), &(hp->arr[father]));
			father=child;
			child = 2 * father + 1;
		}
		else
			break;
	}
}

堆的插入

为了不破坏堆的性质,我们在堆的最后进行插入(想一下其实在最后进行插入就不需要调整其他的元素了)
插入完成之后,我们需要调整成堆的形式。这里我们用堆的向上调整算法。进行调整.

void HeapPush(Heap* hp, HPDataType x)
{
	assert(hp);
	if (hp->size == hp->capacity)
	{
		int newcapcity = hp->capacity == 0 ? 4 : hp->capacity * 2;
		HPDataType* newarr = (HPDataType*)realloc(hp->arr, newcapcity * sizeof(HPDateType));
		if (newarr == NULL)
			exit(-1);
		hp->arr = newarr;
		hp->capacity = newcapcity;
	}
	hp->arr[hp->size] = x;
	hp->size++;

	//向上调整
	adjustup(hp,hp->size-1);
}

堆的删除

对于删除堆头的数据,我们是把堆尾的数据覆盖头,元素个数减1,然后用堆的向下调整算法,进一步调整成堆。

void HeapPop(Heap* hp)
{
	assert(hp);
	assert(hp->size);
	
	swap(&(hp->arr[0]), &(hp->arr[hp->size-1]));
	hp->size--;
	//向下调整
	adjustdown(hp,0);
}

堆的销毁

void HeapDestrop(Heap* hp)
{
	assert(hp);
	free(hp->arr);
	hp->size = hp->capacity = 0;
}

打印堆

void HeapPrint(Heap* hp)
{
	assert(hp);
	for (int i = 0; i < hp->size; i++)
	{
		printf("%d ", hp->arr[i]);
	}
	printf("\n");
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:26:10  更:2022-06-01 15:26:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 0:52:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码