数据结构——栈和队列

数据结构的三要素:

  • 逻辑结构;
  • 元素的运算;
  • 存储结构;

栈 (stack)

定义:

线性表分为两种,一种是顺序表,一种是链表。而栈也可以理解为一种特殊的线性表;


栈只允许在一段进行数据的插入或者删除操作,也就是数据是后进先出;

基本操作

  • InitStack(); 初始化一个栈,分配内存空间;
  • DestoryStack(&S); 销毁一个栈,释放内存空间;
  • Push(&s, value); 若栈未满则向栈顶压入元素value;
  • Pop(&s, output); 若栈非空,则弹出栈顶元素并用output接收;
  • GetTop(&s, output); 若栈非空,则读取栈顶元素并用output接收;
  • bool StackEmpty(s); 判断栈是否为空;

顺序栈的实现与操作

cpp 复制代码
#include <iostream>
using namespace std;

template <class T>
struct Node
{
	//记录栈底的地址
	T* pos;
	//记录栈顶元素的相对位置
	int top;
};

template<class T>
class MyStack
{
private:
	Node<T> d;
	//记录栈的最大容量
	int capacity;
public:
	MyStack()
	{
		capacity = 10;
		d.top = -1;
		d.pos = new T[capacity];
	}

	MyStack(int n)
	{
		capacity = n;
		d.top = -1;
		d.pos = new T[capacity];
	}

	bool StackEmpty()
	{
		return d.top == -1;
	}

	void Push(T value)
	{
		if (d.top != capacity - 1)
		{
			d.pos[++d.top] = value;
		}
		else
		{
			cout << "栈已满" << endl;
			exit(0);
		}
	}

	void Pop(T &output)
	{
		if (!StackEmpty())
		{
			output = d.pos[d.top--];
		}
		else
		{
			cout << "栈已空" << endl;
		}
	}

	void GetTop(T &output)
	{
		if (!StackEmpty())
		{
			output = d.pos[d.top];
		}
		else
		{
			cout << "栈已空" << endl;
		}
	}

	~MyStack()
	{
		delete[] d.pos;
		d.pos = NULL;
	}
};

void test()
{
	MyStack<int> s;
	int n = 0;
	s.Push(10);
	if (!s.StackEmpty())
	{
		cout << "栈非空" << endl;
	}
	s.GetTop(n);
	cout << n << endl;
	s.Pop(n);
	if (s.StackEmpty())
	{
		cout << "成功弹出" << endl;
	}
}

int main()
{
	test();
	return 0;
}

共享栈

由于顺序栈的存储空间相对固定,所以在使用时会有一定的不便:如果开始分配的内存小了可能会出现内存不够用的问题,如果一开始就分配很大的内存又会有空间浪费的问题,这时候用共享栈就可以很好的解决这个问题;


顾名思义,共享栈就是两个栈公用一块内存,但是两个栈的top在最开始分别指向这块内存的两端,并以此为起点压入数据。


需要注意的是 使用共享栈时一定要注意内存是否用完,否则可能出现越界访问的问题;

链式栈的实现

链式栈本质可以看作是一个单链表,只是限制了结点的增删操作只能在链表的一端进行;

队列

定义

队列同样是一个操作受限的线性表,队列只允许在一段进行插入,在另一端进行删除;


允许插入的一段叫做队尾,允许删除的一段叫做对头;

基本操作

队列的基本操作同样是创 销 增 删 查;

  • Init()
  • Destory()
  • Push()
  • Pop()
  • GetHead()
  • Empty()

队列的实现与操作

cpp 复制代码
#include <iostream>
using namespace std;

template<class T>
struct Node
{
	T data;
	Node* next;
	Node(T value)
	{
		data = value;
		next = NULL;
	}
	~Node()
	{
		next = NULL;
	}
};

template <class T>
class MyQueue
{
private:
	Node<T>* n;
	Node<T>* Head;
	Node<T>* Tail;
public:
	MyQueue()
	{
		Head = NULL;
		Tail = NULL;
	}
	MyQueue(T value)
	{
		n = new Node(value);
		n->data = value;
		n->next = NULL;
		Head = &n;
		Tail = &n;
	}
	~MyQueue()
	{
		Node<T>* temp = Head;
		while (Head)
		{
			Head = Head->next;
			delete temp;
			temp = Head;
		}
	}
	bool Empty()
	{
		return Tail == NULL && Head == NULL;
	}
	void Push(T value)
	{
		if (Empty())
		{
			n = new Node<T>(value);
			Head = n;
			Tail = n;
		}
		else
		{
			Tail->next = new Node<T>(value);
			Tail = Tail->next;
			Tail->next = NULL;
		}
	}
	void Pop()
	{
		if (Empty())
		{
			cout << "队列已空" << endl;
			exit(0);
		}
		else if (Tail == Head)
		{
			delete Tail;
			Tail = NULL;
			Head = NULL;
		}
		else
		{
			Node<T>* temp = Head;
			Head = Head->next;
			delete temp;
			temp = NULL;
		}
	}
	T GetTop()
	{
		if (Empty())
		{
			cout << "队列已空" << endl;
			exit(0);
		}
		else
		{
			return Head->data;
		}
	}
};

void test()
{
	MyQueue<int> q;
	q.Push(1);
	q.Push(2);
	q.Push(3);
	while (!q.Empty())
	{
		cout << q.GetTop() << endl;
		q.Pop();
	}
}

int main()
{
	test();
	return 0;
}

总结

  • 栈和队列都是增删操作受限制的特殊线性表;
  • 栈和队列的物理结构可以是连续的也可以是不连续的;
  • 另外,栈和队列的元素都是不能自由访问的。栈只能访问栈顶的元素,队列只能访问对头的元素;
相关推荐
瓜瓜怪兽亚2 小时前
前端基础知识---10 Node.js(三)
数据结构·数据库·node.js
机器学习之心7 小时前
多目标鲸鱼优化算法(NSWOA),含46种测试函数和9个评价指标,MATLAB实现
算法·matlab·多目标鲸鱼优化算法·46种测试函数·9个评价指标
古译汉书8 小时前
嵌入式铁头山羊STM32-各章节详细笔记-查阅传送门
数据结构·笔记·stm32·单片机·嵌入式硬件·个人开发
max5006008 小时前
基于Meta Llama的二语习得学习者行为预测计算模型
人工智能·算法·机器学习·分类·数据挖掘·llama
橘颂TA9 小时前
【数据结构】解锁数据结构:通往高效编程的密钥
数据结构
王哥儿聊AI9 小时前
Lynx:新一代个性化视频生成模型,单图即可生成视频,重新定义身份一致性与视觉质量
人工智能·算法·安全·机器学习·音视频·软件工程
手握风云-11 小时前
优选算法的寻踪契合:字符串专题
算法
闭着眼睛学算法11 小时前
【华为OD机考正在更新】2025年双机位A卷真题【完全原创题解 | 详细考点分类 | 不断更新题目 | 六种主流语言Py+Java+Cpp+C+Js+Go】
java·c语言·javascript·c++·python·算法·华为od
IT古董11 小时前
【第五章:计算机视觉-项目实战之目标检测实战】2.目标检测实战:中国交通标志检测-(2)中国交通标志检测数据格式转化与读取
算法·目标检测·计算机视觉