数据结构:栈堆

文章目录

stack

stack的基本操作

初始化栈

cpp 复制代码
stack<int> st;

empty()

检测栈是否为空。

cpp 复制代码
st.empty();

size()

返回栈中的元素个数。

cpp 复制代码
st.size();

top()

返回栈顶元素的引用。

cpp 复制代码
st.top();

push(val)

将元素val压入stack中。

cpp 复制代码
st.push(val);

pop()

将栈中尾部的元素弹出。

cpp 复制代码
st.pop();

借助容器实现栈

借助vector容器实现栈。

cpp 复制代码
namespace Jnn{
	//Container适配转换出Stack
	template<class T, class Container = vector<T>>
	class stack {
	public:
		void push(const T& x) {
			_con.push_back(x);
		}

		void pop() {
			_con.pop_back();
		}

		const T& top() {
			return _con.back();
		}

		size_t size() const{
			return _con.size();
		}

		bool empty() const {
			return _con.empty();
		}
		
	private:
		Container _con;
	};
}

queue

queue的基本操作

初始化队列

cpp 复制代码
queue<int> q;

empty()

检测队列是否为空。

cpp 复制代码
q.empty();

size()

返回队列中的元素个数。

cpp 复制代码
q.size();

front()

返回对头元素的引用。

cpp 复制代码
q.front();

back()

返回队尾元素的引用。

cpp 复制代码
q.back()

push(val)

将元素val压入队尾中。

cpp 复制代码
q.push(val);

pop()

将队头的元素弹出。

cpp 复制代码
st.pop();

借助容器实现队

借助双端队列实现队。

cpp 复制代码
namespace Jnn {
	template<class T, class Container = deque<T>>
		class queue {
		public:
			void push(const T& x) {
				_con.push_back(x);
			}

			void pop() {
				_con.pop_front();
			}

			const T& front() {
				return _con.front();
			}

			const T& back() {
				return _con.back();
			}

			size_t size const() {
				return _con.size();
			}

			bool empty const() {
				return _con.empty();
			}
		private:
			Container _con;
	};
}

priority_queue

默认情况下,priority_queue是大堆。

父节点和子节点的关系。左孩子=父节点2+1;有孩子=父节点 2+2;父节点=(孩子-1)/2;

priority_queue基本使用

初始化堆

cpp 复制代码
priority_queue<int> 1;

empty()

检测d堆是否为空。

cpp 复制代码
q.empty();

size()

返回堆中的元素个数。

cpp 复制代码
q.size();

top()

返回堆顶元素的引用。

cpp 复制代码
q.top();

push(val)

将元素val压入堆中。

cpp 复制代码
q.push(val);

pop()

将推顶部的元素弹出。

cpp 复制代码
st.pop();

使用容器实现priority_queue

仿函数

本质是一个类,这个类重载了operator(),他的对象可以像函数一样使用。

cpp 复制代码
template<class T>
class Less {
public:
	bool operator()(const T& x, const T& y) {
		return x < y;
	}
};

template<class T>
class Greater {
public:
	bool operator()(const T& x, const T& y) {
		return x > y;
	}
};

向上调整

_con相当于容器,目前先不用管,在稍后的代码中进行讲解。

com是一种比较方式

cpp 复制代码
void AdjustUp(int child) {

	Compare com;

	int parent = (child - 1) / 2;
	while (child > 0) {
		//if (_con[child] > _con[parent]) {
		if (com(_con[child], _con[parent])) {
			swap(_con[child], _con[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else {
			break;
		}
	}
}
void 

push

1.要保证父节点始终大于/小于子节点。

cpp 复制代码
void push(const T& x){
	_con.push_back(x);
	AdjustUp(size()-1);
}

向下调整

cpp 复制代码
void AdjustDown(int parent) {

	Compare com;

	//先假设左孩子小
	size_t child = parent * 2 + 1;
	while (child < _con.size()) {  //child>=n 说明孩子不存在,调整到叶子了
		//找出大的那个孩子
		//if (child + 1 < _con.size() && _con[child + 1] > _con[child]) {
		if (child + 1 < _con.size() && com(_con[child],_con[child+1])) {
			child++;
		}
		
		//if (_con[child] > _con[parent]) {
		if (com(_con[parent], _con[child])) {
			swap(_con[child], _con[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else {
			break;
		}
	}
}

pop()

删除的是根节点,为了保证推的特性,将根节点的数据和最后一个节点的数据进行调换后,删除最后一个节点,从根节点向下进行调整。

cpp 复制代码
void pop() {
	swap(_con[0], _con[_con.size() - 1]);
	_con.pop_back();
	AdjustDown(0);

}

top()

返回根节点的数据。

cpp 复制代码
const T& top() {
	return _con[0];
}

size()

返回推放入有效节点数。

cpp 复制代码
size_t size() const {
	return _con.size();
}

empty()

判断堆是否尾空。

cpp 复制代码
bool empty() const {
	return _con.empty();
}

priority_queue源代码

cpp 复制代码
#pragma once
#include<vector>
#include<queue>
#include<algorithm>

// 仿函数:本质是一个类,这个类重载了operator(),他的对象可以像函数一样使用
template<class T>
class Less {
public:
	bool operator()(const T& x, const T& y) {
		return x < y;
	}
};

template<class T>
class Greater {
public:
	bool operator()(const T& x, const T& y) {
		return x > y;
	}
};

namespace Jnn {
	template<class T, class Container = vector<T>, class Compare = Less<int>>
	class PriorityQueue {
	public:
		void AdjustUp(int child) {

			Compare com;

			int parent = (child - 1) / 2;
			while (child > 0) {
				//if (_con[child] > _con[parent]) {
				if (com(_con[child], _con[parent])) {
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else {
					break;
				}
			}
		}
		void push(const T& x){
			_con.push_back(x);
			AdjustUp(size()-1);
		}

		void AdjustDown(int parent) {

			Compare com;

			//先假设左孩子小
			size_t child = parent * 2 + 1;
			while (child < _con.size()) {  //child>=n 说明孩子不存在,调整到叶子了
				//找出大的那个孩子
				//if (child + 1 < _con.size() && _con[child + 1] > _con[child]) {
				if (child + 1 < _con.size() && com(_con[child],_con[child+1])) {
					child++;
				}
				
				//if (_con[child] > _con[parent]) {
				if (com(_con[parent], _con[child])) {
					swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else {
					break;
				}

			}
		}
		void pop() {
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			AdjustDown(0);

		}

		const T& top() {
			return _con[0];
		}

		size_t size() const {
			return _con.size();
		}

		bool empty() const {
			return _con.empty();
		}
	private:
		Container _con;
	};
}

觉得我回答有用的话,记得点个关注哟!谢谢支持!

相关推荐
二哈赛车手4 小时前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
为何创造硅基生物5 小时前
C语言 结构体内存对齐规则(通俗易懂版)
c语言·开发语言
吃好睡好便好5 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
栗子~~5 小时前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
星寂樱易李5 小时前
iperf3 + Python-- 网络带宽、网速、网络稳定性
开发语言·网络·python
YDS8295 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
仰泳之鹅5 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
之歆5 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
未若君雅裁6 小时前
MyBatis 一级缓存、二级缓存与清理机制
java·缓存·mybatis
cen__y7 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git