0
点赞
收藏
分享

微信扫一扫

C语言 | 如何用两个栈模拟队列

伊人幽梦 2022-04-03 阅读 103

栈与队列的性质及区别

栈与队列都是线性结构,栈类似于弹夹,只能在一端(栈顶)插入以及删除数据,而队列类似于现实中排队,只能再一端(队尾)插入数据,另一端(队首)删除数据。

用两个栈实现队列

1.模拟队列的结构

我们可以用两个栈来实现一个队列,方法是一个栈专门用来入数据(入队列),另一个专门出数据(出队列)。

实现之前要确保已经实现好了一个能完成各项基本操作的栈结构:

typedef int StackDataType;

typedef struct Stack {
	StackDataType* arr;
	size_t top;
	size_t capacity;
}Stack;

void StackInit(Stack* ps);//初始化
void StackDestory(Stack* ps);//销毁
void StackPush(Stack* ps, StackDataType x);//压栈
void StackPop(Stack* ps);//出栈
bool StackEmpty(Stack* ps);//判断是否为空栈
StackDataType StackTop(Stack* ps);//访问栈顶元素
size_t StackSize(Stack* ps);//获取栈的大小

则模拟的队列结构如下:

typedef struct {
    Stack PushStack;
    Stack Poptack;
} MyQueue;

2.实现队列的基础操作

操作清单:

MyQueue* Create() 创建一个队列返回它的地址 
void push(MyQueue* obj,int x)  将元素 x 推到队列的末尾
int pop(MyQueue* obj)  从队列的开头移除并返回元素
int peek(MyQueue* obj)  返回队列开头的元素
bool empty(MyQueue* obj)  如果队列为空,返回 true ;否则,返回 false

1.初始化

MyQueue* myQueueCreate() {
    MyQueue*newqueue=malloc(sizeof(MyQueue));
    StackInit(&newqueue->PuStack);
    StackInit(&newqueue->PoStack);
    return newqueue;
}

创建一个模拟队列,将其中的两个栈分别初始化后返回模拟队列的指针。

2. 入队列

void myQueuePush(MyQueue* obj, int x) {
    StackPush(&obj->PuStack,x);
}

将数据压入专门用于入数据的栈。

3.出队列

int myQueuePop(MyQueue* obj) {
    if(StackEmpty(&obj->PoStack)){
        while(!StackEmpty(&obj->PuStack)){
            StackPush(&obj->PoStack,StackTop(&obj->PuStack));
            StackPop(&obj->PuStack);
        }
    }
    int ret=StackTop(&obj->PoStack);
    StackPop(&obj->PoStack);
    return ret;
}

队列出数据相当于是出入数据的栈中栈底的元素,而栈却只能在栈顶删除数据,所以我们只需要将入数据的栈中每一个数据都倒入专门出数据的栈,原本入数据栈中 栈底的元素就变为了出数据栈中的栈顶元素,故只要当出数据栈的栈顶不为空,我们依次出栈就满足队列的“先进先出”原则,若为空则将入数据栈中的元素都倒过来即可。

4.访问队头元素

int myQueuePeek(MyQueue* obj) {
    if(StackEmpty(&obj->PoStack)){
        while(!StackEmpty(&obj->PuStack)){
            StackPush(&obj->PoStack,StackTop(&obj->PuStack));
            StackPop(&obj->PuStack);
        }
    }
    return StackTop(&obj->PoStack);
}

对头元素就是队列中第一个待出的元素。

5.检查队列是否为空

bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(&obj->PoStack)&&StackEmpty(&obj->PuStack);
}

6.销毁队列

void myQueueFree(MyQueue* obj) {
    StackDestory(&obj->PoStack);
    StackDestory(&obj->PuStack);
}

 

 

举报

相关推荐

0 条评论