判断出栈顺序是否正确
问题描述
给出入栈序列,判断给出的出栈序列是否正确,如入栈顺序为1,2,3,4,5,出栈顺序为2,3,1,5,4,判断该出栈顺序是否有错
解决思路
- 初始化一个空栈,用于模拟入栈和出栈的过程。
- 遍历给定的出栈序列。 a. 对于每一个出栈元素,先检查栈顶元素是否与当前出栈元素相等。如果相等,则出栈栈顶元素。 b. 如果栈顶元素不等于当前出栈元素,说明栈中元素与出栈序列不匹配,此时需要进行入栈操作,将入栈序列中的元素依次入栈,直到栈顶元素与当前出栈元素相等,然后再出栈栈顶元素。 c. 继续遍历下一个出栈元素,重复步骤 a 和步骤 b。
- 最终,如果所有的出栈元素都按照正确的顺序进行出栈,并且栈为空,说明出栈序列是正确的,否则是错误的。
代码实现
bool IsOutOrder(int* inoder, int* outoder, int len) {
LinkStack stack;
InitStack(&stack);
int val;
int i = 0, j = 0;
while (j < len) {
if (!IsEmpty(&stack) && GetTop(&stack, &val) && val == outoder[j]) {
// 栈顶元素与出栈序列当前元素相等,进行出栈
Pop(&stack);
j++;
}
else {
// 栈为空或者栈顶元素与出栈序列当前元素不相等,进行入栈
if (i >= len) {
// 入栈序列已经遍历完,无法继续入栈
return false;
}
Push(&stack, inoder[i]);
i++;
}
}
// 遍历完出栈序列后,检查栈是否为空
while (!IsEmpty(&stack)) {
// 如果栈顶元素与出栈序列的当前元素相等,进行出栈
if (GetTop(&stack, &val) && val == outoder[j]) {
Pop(&stack);
j++;
}
else {
// 出栈序列不匹配
return false;
}
}
// 如果出栈序列匹配,并且栈已经为空,则说明出栈序列是正确的
return IsEmpty(&stack);
}
两个栈模拟队列
- 定义两个栈,一个用于入队操作(称为 "入队栈"),另一个用于出队操作(称为 "出队栈")。
- 对于入队操作,直接将元素压入 "入队栈" 即可。
- 对于出队操作,先检查 "出队栈" 是否为空,如果为空,则将 "入队栈" 中的元素全部出栈并压入 "出队栈",然后再从 "出队栈" 弹出栈顶元素作为出队结果。如果 "出队栈" 不为空,直接从 "出队栈" 弹出栈顶元素即可。
- 如果 "入队栈" 和 "出队栈" 都为空,表示队列为空。
- 需要注意的是,为了实现队列的 FIFO 特性,出队操作只能从 "出队栈" 中弹出元素。
代码实现
typedef struct Queue {
LinkStack stack1;
LinkStack stack2;
}Queue;
void InitQueue(Queue* queue) {
InitStack(&queue->stack1);//入队栈
InitStack(&queue->stack2);//出队栈
}
bool IsEmptyQueue(Queue* queue) {
return IsEmpty(&queue->stack1) && IsEmpty(&queue->stack2);
}
void enqueue(Queue* queue, int val) {
Push(&queue->stack1, val);
}
int PopQueue(Queue* queue) {
while (!IsEmpty(&queue->stack1)) {
int val1=Pop(&queue->stack1);
Push(&queue->stack2,val1);
}
return Pop(&queue->stack2);
}
有关栈的函数再上一篇
两个队列模拟栈
-
创建两个队列 Queue1 和 Queue2。
-
入栈操作(push):
- 把元素压入非空的队列(假设为 Queue1)中。
-
出栈操作(pop):
- 将非空队列(假设为 Queue1)中的元素依次出队并入队到另一个空队列(假设为 Queue2),直到队列中只剩下一个元素。
- 然后将这个剩下的元素出队,即为要出栈的元素。
-
查看栈顶元素(top):
- 与出栈操作类似,先将非空队列中的元素移动到另一个空队列中,直到只剩下一个元素。
- 这个剩下的元素即为栈顶元素。
-
判断栈是否为空(empty):
- 若两个队列都为空,则栈为空,否则栈非空。
代码实现
typedef struct Stack {
LinkQueue queue1;
LinkQueue queue2;
}Stack;
void InitStack(Stack* stack) {
InitQueue(&stack->queue1);
InitQueue(&stack->queue2);
}
bool IsEmptyStack(Stack* stack) {
return IsEmpty(&stack->queue1) && IsEmpty(&stack->queue2);
}
void PushStack(Stack* stack, int val) {
PushQueue(&stack->queue1, val);
}
int PopStack(Stack* stack) {
if (!IsEmpty(&stack->queue1)) {
if (stack->queue1.size == 1) {
return PopQueue(&stack->queue1);
}
else {
while (stack->queue1.size > 1) {
int val = PopQueue(&stack->queue1);
PushQueue(&stack->queue2, val);
}
int val1 = PopQueue(&stack->queue1);
while (!IsEmpty(&stack->queue2)) {
int val2 = PopQueue(&stack->queue2);
PushQueue(&stack->queue1, val2);
}
return val1;
}
}
return -1;
}