栈和队列理论基础
文章链接:link
1.基本概念
栈 stack
push pop
队列 queue
232.用栈实现队列
一、做题感受&第一想法
不知道如何用栈实现队列,也不知道c语言中如何模拟一个栈比较合适。
二、学习文章后收获
1.C语言栈的定义
typedef struct s{
int stack[SIZE]; //栈空间
int stackTop; //栈顶指针
}
2.用栈实现队列:
一个输出栈,一个输入栈。
输入:都压到输入栈
输出:如果输出栈不为空,则输出。否则,将输入栈所有元素逐个弹出栈并压入输出栈中。
3.代码
#define MAX_SIZE 100
typedef struct {
int inStack[MAX_SIZE];
int outStack[MAX_SIZE];
int inTop;
int outTop;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
q->inTop = 0;
q->outTop = 0;
return q;
}
void myQueuePush(MyQueue* obj, int x) {
obj->inStack[obj->inTop] = x;
obj->inTop++;
}
int myQueuePop(MyQueue* obj) {
if(obj->outTop == 0){ //当输出栈为空
while(obj->inTop != 0){ //输入栈全部转移到输出栈
obj->inTop--;
obj->outStack[obj->outTop] = obj->inStack[obj->inTop];
obj->outTop++;
}
}
obj->outTop--;
return obj->outStack[obj->outTop];
}
int myQueuePeek(MyQueue* obj) {
if(obj->outTop == 0){
while(obj->inTop != 0){
obj->inTop--;
obj->outStack[obj->outTop] = obj->inStack[obj->inTop];
obj->outTop++;
}
}
return obj->outStack[obj->outTop - 1];
}
bool myQueueEmpty(MyQueue* obj) {
if(obj->inTop == 0 && obj->outTop == 0){
return true;
}
else{
return false;
}
}
void myQueueFree(MyQueue* obj) {
free(obj);
return;
}
225. 用队列实现栈
一、做题感受&第一想法
使用了两个循环队列。
每次要弹出栈顶元素时,将一号队列中除了最后一个元素全部移动到二号队列中,然后输出一号队列的最后一个元素,此即栈顶元素。
#define MAX_SIZE 101
typedef struct {
int queueOne[MAX_SIZE];
int queueTwo[MAX_SIZE];
int head1,head2;
int tail1,tail2;
} MyStack;
MyStack* myStackCreate() {
MyStack* s = (MyStack*)malloc(sizeof(MyStack));
s->head1 = 0;
s->head2 = 0;
s->tail1 = 0;
s->tail2 = 0;
return s;
}
void myStackPush(MyStack* obj, int x) {
if(obj->head1 == obj->tail1){
obj->queueTwo[obj->tail2] = x;
obj->tail2++;
obj->tail2 %= MAX_SIZE;
}
else{
obj->queueOne[obj->tail1] = x;
obj->tail1++;
obj->tail1 %= MAX_SIZE;
}
return;
}
int myStackPop(MyStack* obj) {
int pop = 0;
if(obj->head2 != obj->tail2){ //1 is empty, 2 is not empty
while((obj->head2 + 1) % MAX_SIZE != obj->tail2){
obj->queueOne[obj->tail1] = obj->queueTwo[obj->head2];
obj->tail1++;
obj->tail1 %= MAX_SIZE;
obj->head2++;
obj->head2 %= MAX_SIZE;
}
pop = obj->queueTwo[obj->head2];
obj->head2++;
obj->head2 %= MAX_SIZE;
}
else if(obj->head1 != obj->tail1){
while((obj->head1 + 1)%MAX_SIZE != obj->tail1){
obj->queueTwo[obj->tail2] = obj->queueOne[obj->head1];
obj->tail2++;
obj->tail2 %= MAX_SIZE;
obj->head1++;
obj->head1 %= MAX_SIZE;
}
pop = obj->queueOne[obj->head1];
obj->head1++;
obj->head1 %= MAX_SIZE;
}
return pop;
}
int myStackTop(MyStack* obj) {
int top = myStackPop(obj);
myStackPush(obj,top);
return top;
}
bool myStackEmpty(MyStack* obj) {
if(obj->head1 == obj->tail1 && obj->head2 == obj->tail2){
return true;
}
else{
return false;
}
}
void myStackFree(MyStack* obj) {
free(obj);
return;
}
二、学习文章后收获
1.代码的复用
比如top函数用于输出栈顶元素,可以先pop,再push。(用已有的功能组合出新的功能。)
2.优化:一个队列实现栈
一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。