首页 > 编程语言 >C++中的堆

C++中的堆

时间:2023-08-14 21:46:52浏览次数:53  
标签:读取 函数 int 元素 C++ heap op

C++中的堆

一、堆的概念

堆是一种特殊的树形数据结构,其每个节点都有一个值。通常所说的堆的数据结构,是指二叉堆,即完全二叉树。在C++中,标准库提供了一些用于操作堆的函数,如make_heap(), push_heap(), pop_heap()等。

二、堆的特点

  1. 每个节点的值都大于或等于(最大堆)或小于或等于(最小堆)其子节点的值;
  2. 堆是完全二叉树;
  3. 在堆中,父节点的值总是大于或等于(最大堆)或小于或等于(最小堆)其子节点的值;
  4. 堆的根节点是整个堆的最大值(或最小值)。

三、堆的实现原理

  1. 建立堆:首先将元素插入到数组中,然后通过调整数组中的元素,使其满足堆的性质。这个过程通常使用make_heap()函数来完成。
  2. 调整堆:在插入新元素后,需要调整堆以保持其性质。这个过程通常使用push_heap()函数来完成。
  3. 删除堆顶元素:在需要删除堆顶元素时,首先需要将堆调整为最大堆或最小堆,然后再进行删除操作。这个过程通常使用pop_heap()函数来完成。

四、堆的算法流程

  1. 插入元素:首先将元素插入到数组中,然后通过调整数组中的元素,使其满足堆的性质。
  2. 调整堆:在插入新元素后,需要调整堆以保持其性质。这个过程通常使用push_heap()函数来完成。
  3. 删除堆顶元素:在需要删除堆顶元素时,首先需要将堆调整为最大堆或最小堆,然后再进行删除操作。这个过程通常使用pop_heap()函数来完成。
  4. 获取最大/小值:如果需要获取当前堆的最大值或最小值,可以使用top()函数来获取。如果需要获取最大/小值的索引,可以使用bottom()函数来获取。

五、C++代码示例

#include<bits/stdc++.h>  // 引入头文件,包含了常用的标准库函数和数据结构
#define reg register  // 定义宏,表示使用寄存器变量
using namespace std;  // 使用命名空间std,简化代码书写

// 定义一个函数read(),用于读取输入的整数,支持负数输入
inline int read(){
	int x=0,f=1;  // 初始化变量x为0,f为1
	char ch=getchar();  // 读取一个字符作为输入
	while(ch<'0'||ch>'9'){  // 如果输入不是数字,则继续读取
		if(ch=='-')	f=-1;  // 如果输入是负号,则将f设为-1
		ch=getchar();  // 读取下一个字符
	}
	while(ch>='0'&&ch<='9'){  // 如果输入是数字,则转换为整数并计算结果
		x=(x<<1)+(x<<3)+(ch^48);  // 将x左移1位并加上x左移3位再加上ch与48的异或值
		ch=getchar();  // 读取下一个字符
	}
	return x*f;  // 返回计算结果,如果f为-1,则返回负数结果
}

// 定义一个函数write(),用于输出整数,支持负数输出
void write(int x){
	if(x<0){  // 如果x是负数,则先输出负号
		putchar('-');
		x=-x;  // 取绝对值
	}
	if(x>9)	write(x/10);  // 如果x大于9,则递归调用write()函数输出除以10的结果
	putchar(x%10+'0');  // 输出x除以10的余数,并转换为字符输出
	return ;
}

int n;  // 声明一个整数变量n,用于存储操作的次数
priority_queue<int, vector<int > ,greater<int > > a;  // 声明一个优先队列a,用于存储整数,默认为大顶堆

int main(){
	n=read();  // 读取操作次数n
	while(n--){  // 循环执行n次操作
		int op=read();  // 读取操作类型op
		if(op==1){  // 如果操作类型op为1,则读取一个整数x,并将其插入到优先队列a中
			int x;
			scanf("%d",&x);
			a.push(x);
			continue;
		}
		if(op==2){  // 如果操作类型op为2,则输出优先队列a的顶部元素(即最小值)
			printf("%d\n",a.top());
			continue;
		}
		if(op==3){  // 如果操作类型op为3,则弹出优先队列a的顶部元素(即最小值)
			a.pop();
		}
	}
	return 0;  // 程序执行完毕,返回0
}

在这个例子中,我们首先定义了一个大小为100的数组作为堆,然后插入了三个元素3、5和1。最后,我们调用pop_max()函数来删除并返回堆中的最大元素。

标签:读取,函数,int,元素,C++,heap,op
From: https://www.cnblogs.com/Nebulary/p/17629832.html

相关文章

  • C/C++内存管理
    一、C/C++内存分布看下面这段代码:intglobalVar=1;staticintstaticGlobalVar=1;voidTest1(){ staticintstaticVar=1; intlocalVar=1; intnum1[10]={1,2,3,4}; charchar2[]="abcd"; constchar*pChar3="abcd"; int*ptr1=(int*......
  • C/C++内存管理
    一、C/C++内存分布看下面这段代码:intglobalVar=1;staticintstaticGlobalVar=1;voidTest1(){ staticintstaticVar=1; intlocalVar=1; intnum1[10]={1,2,3,4}; charchar2[]="abcd"; constchar*pChar3="abcd"; int*ptr1=(int*......
  • c++ std::to_string实现原理
    写这篇的起因是看到MSVCSTL的一个issue,里面提到to_string<int>的实现,正常人的思维是直接除10拿到每位,其实有个更高效的查表法字符串转数字除100拿到两位,并查表填入,少了一半的除法,代价是需要一个201个byte的空间,下面是gcc的实现//Writeanunsignedintegervaluetother......
  • 位运算 学习笔记【C++ 算法竞赛】
    大家好,欢迎来到我的第一篇博客位运算和移位运算作为计算机的基本运算之⼀,其都是对⼆进制位进⾏操作。作为近年算法竞赛笔试较热门的考点,它能够快捷地完成特定的应用。掌握它是⾮常有必要的。以下是目录:目录1.位运算的优先级2.左移运算<<、右移运算>>2.1运算规则:2.2应用:......
  • Go/C++/Java中的数组对比
    数组是大多数编程语言中的基本数据结构。然而,不同的编程语言对数组的实现和语义有所不同。以下是Go、C++和Java中数组的主要区别:1.基本性质Go:数组是值类型。赋值或将数组传递给函数时,内容会被复制。数组的大小是其类型的一部分。因此,具有不同大小的数组被认为是不同......
  • C++系列一:语言基础-杂烩2
    @目录前言:信号处理前言:继续……信号处理信号是由操作系统传给进程的中断,会提早终止一个程序。头文件中。SIGABRT 程序的异常终止,如调用abort。SIGFPE 错误的算术运算,比如除以零或导致溢出的操作。SIGILL 检测非法指令。SIGINT 程序终止(interrupt)信号。SIGSEGV 非......
  • C++容器---关联式容器<set>&<multiset>
    由于multiset和set相差不大,所以基本以set做练习;集合(Set)是一种包含已排序(升序)对象的关联容器。set/multiset会根据待定的排序准则,自动将元素排序。两者不同在于前者不允许元素重复,而后者允许。集合元素既充当数据,又充当关键码,以升序的顺序存储;multiset中的元素可以重复。1)不能直......
  • C++容器---关联式容器<map>&<multimap>
    由于multimap和map相差不大,所以基本以map做练习;集合(map)是一种包含已排序(升序)对象的关联容器。map/multimap会根据待定的排序准则,自动将元素排序。两者不同在于前者不允许元素重复,而后者允许。集合元素的第一个参数是key,第二个元素当做value,元素的顺序与key有关,与value无关;模板原......
  • python打包库nuitka测试 是否和c++的速度差不多
    nuitka一个打包py脚本的库原理是把py代码转成c++代码再重新编译宣传的优点是打包的程序速度快占用空间小用了一些时间了突然想测试一下性能是否和宣传的一样写了一个输出一百万以内素数个数的脚本 打包成exe结果  不打包执行 说实话挺失望还剩一个优点空间......
  • C++使用new来初始化指向类的指针
    C++使用new来初始化类的指针1.ClassName*p=newClassName;调用默认构造函数。如果类里没有写默认构造函数,会使用编译器帮我们生成的,但不会初始化成员变量,如classNoConstructor//没写构造函数的类{public:~NoConstructor(){}voidprintVal(){......