第3章 栈和队列
一、小状元课上习题
1、有tag标记的循环队列(同王道3.2.5_01)
题目
类型中增设tag数据成员,当tag为0,若因删除导致Q.front == Q.rear,则队空。当tag为1,若因插入导致Q.front == Q.rear,则队满。请设计入队和出队操作
【注意】:南邮教材中。front和rear指向与王道的不同
1、front指向:队头元素的前一个位置。因此删除操作:先移指针,再删元素
2、rear指向:队尾元素。因此插入操作:先移指针,再放元素
思路
插入:
1、先判断队列是否已满
2、rear指向:队尾元素。因此插入操作:先移指针,再放元素。
删除
1、先判断队列是否为空
2、front指向:队头元素的前一个位置。因此删除操作:先移指针,再删元素
// 入队
bool EnQueue(Queue &Q, int x)
{
if (Q.tag == 1 && Q.front == Q.rear) // 队列已满
return false;
else
{
Q.rear = (Q.rear + 1) % MaxSize; // rear指针指向队尾元素,因此先移动指针
Q.data[Q.rear] = x; // 再插入元素。
Q.tag = 1; // 插入操作可能导致队列满,因此把tag置为1
return true;
}
}
// 出队
bool DeQueue(Queue &Q, int &x)
{
if (Q.tag == 0 && Q.front == Q.rear) // 队列为空
return false;
else
{
Q.front = (Q.front + 1) % MaxSize; // front指向:队头元素的前一个位置。因此删除操作:先移指针
x = Q.data[Q.front]; // 再删元素
Q.tag = 0; // 删除操作可能导致队空,因此把tag置为0
return true;
}
}
2、一种类型的括号匹配
题目
设计一个括号匹配算法(仅有一种括号类型)
思路
依次遍历整个字符数组,
1、如果当前字符为左括号,则把左括号进栈
2、如果当前字符为右括号,并且栈不为空,则把栈顶的左括号出栈。否则(栈为空),返回false,匹配失败
3、遍历结束后,如果栈为空则返回true,否则返回false,匹配失败
bool matchBrackets(char str[], int length) // str为字符数组,length为数组长度
{
int i, top = -1; // top用来表示栈的栈顶指针
for (i = 0; i < length; i++)
{
if (str[i] == '(') // 如果当前字符为左括号,则把左括号进栈
top++;
else
{
if (top > -1) // 如果当前字符为右括号,并且栈不为空,说明有一对括号匹配成功,则把栈顶的左括号出栈
top--;
else // 否则(栈为空),返回false,匹配失败
return false;
}
}
if (top == -1) return true; // 遍历结束后,如果栈为空则返回true,否则返回false,匹配失败
else return false;
}
3、多种类型的括号匹配(王道课件)
二、王道(3.2.5)
01(同小状元第一题,但是答案与小状元的不同)
题目
02
题目
思路
1、将队列中的全部元素依次出队,并且入栈
2、将栈中全部元素入队
参考答案
03
题目
思路
入队用S1,出队用S2
Enqueue:
1、如果S1不满,则直接入栈
2、S1满并且S2不为空,说明栈满,返回false
3、S1满但S2为空,把S1的所有元素放入S2中,再在S1中进行插入操作
Dequeue:
1、如果S2不为空,则S2的栈顶元素出栈
2、如果S1为空,说明队列为空,返回false
3、如果S2为空,则把S1中全部元素放入S2中,全部放入完毕后S2的栈顶出栈
QueueEmpty:
判断S1、S2是否为同时空
参考答案