数据结构——栈和队列

数据结构的三要素:

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

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

总结

  • 栈和队列都是增删操作受限制的特殊线性表;
  • 栈和队列的物理结构可以是连续的也可以是不连续的;
  • 另外,栈和队列的元素都是不能自由访问的。栈只能访问栈顶的元素,队列只能访问对头的元素;
相关推荐
yuuki2332331 小时前
【数据结构】用顺序表实现通讯录
c语言·数据结构·后端
DashVector2 小时前
向量检索服务 DashVector产品计费
数据库·数据仓库·人工智能·算法·向量检索
AI纪元故事会2 小时前
【计算机视觉目标检测算法对比:R-CNN、YOLO与SSD全面解析】
人工智能·算法·目标检测·计算机视觉
夏鹏今天学习了吗2 小时前
【LeetCode热题100(59/100)】分割回文串
算法·leetcode·深度优先
卡提西亚2 小时前
C++笔记-10-循环语句
c++·笔记·算法
还是码字踏实2 小时前
基础数据结构之数组的双指针技巧之对撞指针(两端向中间):三数之和(LeetCode 15 中等题)
数据结构·算法·leetcode·双指针·对撞指针
Coovally AI模型快速验证4 小时前
当视觉语言模型接收到相互矛盾的信息时,它会相信哪个信号?
人工智能·深度学习·算法·机器学习·目标跟踪·语言模型
电院工程师5 小时前
SIMON64/128算法Verilog流水线实现(附Python实现)
python·嵌入式硬件·算法·密码学
轮到我狗叫了5 小时前
力扣.84柱状图中最大矩形 力扣.134加油站牛客.abb(hard 动态规划+哈希表)牛客.哈夫曼编码
算法·leetcode·职场和发展
丛雨要玩游戏5 小时前
字符函数和字符串函数
c语言·开发语言·算法