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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 用数组完全二叉树实现堆#C++ -> 正文阅读

[数据结构与算法]用数组完全二叉树实现堆#C++

堆的基本操作

有很多种数据结构可以实现最小堆,包括:
完全二叉树,左偏树,斜堆,二项堆,斐波那契堆等等,完全二叉树是这里面内存利用效率最高的。

  • top:返回当前的最小值
    直接返回根节点,时间复杂度为O(1)
int top()
{
	return h[1];
}
  • pop:弹出当前的最小值 (shift_down)
    删除根节点,递归把子节点补上来
    完全二叉树pop :先把根节点删除,再把最后一个节点移动到根,然后从上往下更新
    在这里插入图片描述
    在这里插入图片描述
void pop()
{
	h[1] = h[heap_size];
	heap_size--;
	shift_down(1); 
}
  • push:插入一个数(shift_up)
    插入根,插入一个空节点
    第一种情况,可以和当前节点比较,保留较小的,大的递归下去插入子树
    第二种情况,如果当前的节点的值小于父节点的值,就和父节点交换,直到大于父节点的值或成为根节点

在这里插入图片描述

void push(int v)
{
	h[++heap_size] = v;
	shift_up(heap_size);
}
  • shift_up
    每次将该元素和其父元素比较,若该元素小于其父元素,则将其父元素与其交换位置,直到达到根节点或者该元素大于其父元素
void shift_up(int x)
{
	if(x == 1)
		return;
	if(h[x] < h[x/2])
	{
		swap(x , x / 2);
		shift_up(x / 2);
	}
}
  • shift_down
    每次将该元素与其左右元素比较,若该元素大于任意一个左右子元素,则将其与左右子元素中的最小的那个交换位置,直到达到叶节点或者该元素小于其两个左右子元素
void shift_down(int x)
{
	if(x * 2 > heap_size)	//终止条件 
		return;
	int k = x;
	if(h[2 * x] < h[k])
		k = x * 2;
	if(x * 2 + 1 <= heap_size && h[x * 2 + 1] < h[k])
		k = k * 2 + 1;
	if(k == x)
		return;
	swap(x , k);
	shift_down(k);
}
  • 时间复杂度分析:
    pop和push的操作都和树的高度正相关
    完全二叉树的树高为log n,所以pop和push的时间复杂度均为O(log n)

测试代码:

样例pop图:
请添加图片描述
样例:输入3 7 9 10 13 21 11 12 八个数,进行测试

#include <iostream>
#include <cstdlib>
using namespace std;
//首先定义一个数组h[]存储堆元素
//定义一个变量heap_size表示堆的大小
const int N = 1001;
int h[N] , heap_size;
/*
1.top
只需要返回根结点 
*/
int top()
{
	return h[1];
}
void swap(int x , int y)
{
	int temp = h[x];
	h[x] = h[y];
	h[y] = temp;
}
/*
2.shift_up操作
从节点x开始向根方向依次比较,x的父节点是x/2 
*/
void shift_up(int x)
{
	if(x == 1)
		return;
	if(h[x] < h[x/2])
	{
		swap(x , x / 2);
		shift_up(x / 2);
	}
}
/*
3.shift_down操作,从节点x开始向子节点方向比较
注意x的左节点是2x,右节点是2x+1
下标不能超过heap_size 
*/
void shift_down(int x)
{
	if(x * 2 > heap_size)	//终止条件 
		return;
	int k = x;
	if(h[2 * x] < h[k])
		k = x * 2;
	if(x * 2 + 1 <= heap_size && h[x * 2 + 1] < h[k])
		k = k * 2 + 1;
	if(k == x)
		return;
	swap(x , k);
	shift_down(k);
}
/*
4.pop操作
把h[1]和最后一个节点交换,向下比较 
*/
void pop()
{
	h[1] = h[heap_size];
	heap_size--;
	shift_down(1); 
}
/*
5.push操作
插在最后一个节点,然后向上比较 
*/
void push(int v)
{
	h[++heap_size] = v;
	shift_up(heap_size);
}
int main()
{
	int n;
	cout << "Please enter the number of data you want to store:" << endl;
	cin >> n;
	cout << "Please enter your data to be pushed:" << endl; 
	for(int i = 1 ; i <= n ; i++)
	{
		int x;
		cin >> x;
		push(x);
	}
	cout << "Output the heap element:" << endl;
	for(int i = 1 ; i <= heap_size ; i++)
		cout << h[i] << " ";
	cout << endl << "Delete the top data:" << endl << top() << endl;
	pop();
	cout << "Now the top data is:" << top() << endl;
	for(int i = 1 ; i <= heap_size ; i++)
		cout << h[i] << " ";
	return 0;
}

运行结果:
请添加图片描述

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-28 12:36:28  更:2021-10-28 12:36:58 
 
开发: 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/26 9:55:54-

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