栈和队列

先进后出, 后进现出

  • 限定仅在表的一端进行插入和删除操作的线性表

操作

  • 初始化
  • 入栈
  • 出栈
  • 取值
  • 判断栈满栈空
  • 双栈共享

顺序栈

// 顺序栈类模板
template<class ElemType>
class SqStack 
{
protected:
// 数据成员:
	ElemType *elems;												// 元素存储空间
	int maxSize;													// 栈最大元素个数
	int count;														// 元素个数

public:
// 抽象数据类型方法声明及重载编译系统默认方法声明:
	SqStack(int size = DEFAULT_SIZE);								// 构造函数模板
	virtual ~SqStack();												// 析构函数模板
	int Length() const;												// 求栈长度			 
	bool Empty() const;												// 判断栈是否为空
	void Clear();													// 将栈清空
	void Traverse(void (*visit)(const ElemType &)) const;			// 遍历栈
	bool Push(const ElemType &e);									// 入栈
	bool Top(ElemType &e) const;									// 返回栈顶元素
	bool Pop(ElemType &e);											// 出栈
	bool Pop();														// 出栈
	SqStack(const SqStack<ElemType> &source);						// 复制构造函数模板
	SqStack<ElemType> &operator =(const SqStack<ElemType> &source);	// 重载赋值运算符
};

判断栈满:count = maxSize
判断栈空:count = 0

链式栈

表头作为栈顶好,入栈方便

// 链栈类模板
template<class ElemType>
class LinkStack 
{
protected:
// 数据成员:
	Node<ElemType> *top;												// 栈顶指针
	int count;															// 元素个数

public:
// 抽象数据类型方法声明及重载编译系统默认方法声明:
	LinkStack();														// 无参数的构造函数模板
	virtual ~LinkStack();												// 析构函数模板
	int Length() const;													// 求栈长度			 
	bool Empty() const;													// 判断栈是否为空
	void Clear();														// 将栈清空
	void Traverse(void (*visit)(const ElemType &)) const ;				// 遍历栈
	bool Push(const ElemType &e);										// 入栈
	bool Top(ElemType &e) const;										// 返回栈顶元素
	bool Pop(ElemType &e);												// 出栈
	bool Pop();															// 出栈
	LinkStack(const LinkStack<ElemType> &source);						// 复制构造函数模板
	LinkStack<ElemType> &operator =(const LinkStack<ElemType> &source);	// 重载赋值运算符
};

入栈:

  1. 建立新的栈顶
  2. 新栈顶指针指向旧栈顶
  3. 栈顶指针赋值新栈顶
  4. 栈元素+1

出栈:

  1. 备份旧栈顶
  2. 栈顶指针赋值旧栈顶->next
  3. 删除旧栈顶

队列

仅在表的一端进行插入,在表的另一端删除
先进先出

队头:删除元素
队尾:插入元素

基本操作:

  1. 入队
  2. 出队
  3. 读取队头元素值
  4. 求队长
  5. 建队列
  6. 判断队满、队空

链队列

需要两个指针frontrear 指向队列队头和队尾

链表头作为队头、链表尾作为队尾好,便于入队出队

为方便加上头接点

入队:

  1. 旧队尾指向新队尾
  2. 队尾指针指向新队尾

出队:

  1. 备份旧队首;
  2. 队首指针赋值指旧队首next
  3. 删除旧队首指针

循环队列(处理顺序链表队列)

顺序链表队列问题:假溢出问题

解决:

  1. 平移,发生假溢出将所有元素移到开头
  2. 使用动态数组,重新分配空间
  3. 使用环形数组
front = (front + 1)%MAXSIZE;
rear = (rear + 1) & MAXSIZE;

当到达顺序表尾时将数据加到开头

但是队列满和空的条件仍相同

解决:

  1. 标志位
  2. 计数器
  3. 少用一个空间,尾指针+1 = 头指针作为队列满的条件

应用

  1. 表达式求值

表达式包括:

  • 操作数
    • 常数
    • 标识符
  • 运算符
    • 算数
    • 逻辑
    • 关系
  • 界限符
    • 括号
    • 结束符

解法:

  1. 设定两栈:操作数或运算结果栈、运算符栈

  2. 操作符的优先级

  3. 序列检测

posted @ 2023-10-19 16:13  Mars-Luke  阅读(32)  评论(0)    收藏  举报