栈和队列问题总结

判断出栈顺序是否正确

问题描述

给出入栈序列,判断给出的出栈序列是否正确,如入栈顺序为1,2,3,4,5,出栈顺序为2,3,1,5,4,判断该出栈顺序是否有错

解决思路

  1. 初始化一个空栈,用于模拟入栈和出栈的过程。
  2. 遍历给定的出栈序列。 a. 对于每一个出栈元素,先检查栈顶元素是否与当前出栈元素相等。如果相等,则出栈栈顶元素。 b. 如果栈顶元素不等于当前出栈元素,说明栈中元素与出栈序列不匹配,此时需要进行入栈操作,将入栈序列中的元素依次入栈,直到栈顶元素与当前出栈元素相等,然后再出栈栈顶元素。 c. 继续遍历下一个出栈元素,重复步骤 a 和步骤 b。
  3. 最终,如果所有的出栈元素都按照正确的顺序进行出栈,并且栈为空,说明出栈序列是正确的,否则是错误的。

代码实现

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);
}

两个栈模拟队列

  1. 定义两个栈,一个用于入队操作(称为 "入队栈"),另一个用于出队操作(称为 "出队栈")。
  2. 对于入队操作,直接将元素压入 "入队栈" 即可。
  3. 对于出队操作,先检查 "出队栈" 是否为空,如果为空,则将 "入队栈" 中的元素全部出栈并压入 "出队栈",然后再从 "出队栈" 弹出栈顶元素作为出队结果。如果 "出队栈" 不为空,直接从 "出队栈" 弹出栈顶元素即可。
  4. 如果 "入队栈" 和 "出队栈" 都为空,表示队列为空。
  5. 需要注意的是,为了实现队列的 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);
}

有关栈的函数再上一篇

两个队列模拟栈

  1. 创建两个队列 Queue1 和 Queue2。

  2. 入栈操作(push):

    • 把元素压入非空的队列(假设为 Queue1)中。
  3. 出栈操作(pop):

    • 将非空队列(假设为 Queue1)中的元素依次出队并入队到另一个空队列(假设为 Queue2),直到队列中只剩下一个元素。
    • 然后将这个剩下的元素出队,即为要出栈的元素。
  4. 查看栈顶元素(top):

    • 与出栈操作类似,先将非空队列中的元素移动到另一个空队列中,直到只剩下一个元素。
    • 这个剩下的元素即为栈顶元素。
  5. 判断栈是否为空(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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值