数据结构:栈堆

文章目录

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

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

相关推荐
QianhangQianping6 分钟前
撤销重做不是「存快照」:一个可视化编辑器的Operation 设计
java·前端·数据库·typescript·编辑器·前端架构·撤销重做
海绵宝宝转agent12 分钟前
LeetCodehot100题解
java·笔记·学习·算法·leetcode·深度优先
SunnyDays101113 分钟前
Java 操作 Word 脚注和尾注:添加、读取与删除
java·word
SunnyDays101114 分钟前
Java 为 Word 添加页码:隐藏封面页码、从指定页开始编号、奇偶页页码设置等
java·word·页码
octopus_c18 分钟前
C++ 运算符重载详解 && 日期类的实现
开发语言·c++
开源推荐官19 分钟前
多门店 O2O 商城选型复盘:从开发视角对比主流开源系统
java·架构·开源·php
吴名氏.19 分钟前
Java转AI Agent教程(第二周)超时重试与错误分类
java·人工智能·python·分类·ai agent
Eiceblue22 分钟前
用 Python 给 Word 文档加水印:文字、图片与批量处理
开发语言·vscode·python·word
j7~26 分钟前
【C++ 面试笔记】(篇二):类与数据抽象 & STL 容器与算法
开发语言·c++·面试·stl容器和算法·类和数据抽象
Fuyo_11191 小时前
深入解析 C++ unordered_set 与 unordered_map 的核心特性与性能实战
开发语言·c++