数据结构:栈堆

文章目录

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;
	};
}

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

相关推荐
CSharp精选营19 小时前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
像我这样帅的人丶你还21 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩21 小时前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构
tntxia1 天前
Mybatis的日志输入
java
亦暖筑序1 天前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
用户298698530141 天前
Java 实现 Word 文档加密与权限解除
java·后端
Yeats_Liao1 天前
14:Servlet中的页面跳转-Java Web
java·后端·架构
未秃头的程序猿1 天前
告别"if-else地狱"!Java 21模式匹配,代码优雅了10倍
java·后端·面试
鹤望兰6751 天前
字节跳动国际支付-后端开发-三面面经
java
Flittly1 天前
【AgentScope Java新手村系列】(14)人机交互
java·spring boot·spring