题目:如下文
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
答案:如下图
typedef int STDataType;
typedef struct Stack
{
STDataType* _a;
int _top;//栈顶
int _capacity;
}Stack;//Stack为结构体
//初始化和销毁
void StackInit(Stack* pst);
void StackDestory(Stack* pst);
//入栈
void StackPush(Stack* pst, STDataType x);
//出栈
void StackPop(Stack* pst);
//获取栈的个数(必定为整数int类型的故采用int)
int StackSize(Stack* pst);
//判断栈是否为空,为空返回1,不为空返回0(0和1一定为整形类型的采用int)
int StackEmpty(Stack* pst);
//获取栈顶的值(一个栈顶的数值有可能不为int类型的,有可能为double类型的,
// 即不为整数,有小数或则其他运算值
STDataType StackTop(Stack* pst);
//初始化和销毁
void StackInit(Stack* pst)
{
//断言指针是否为空,为空直接报错,不为空才可以接收进行访问;
assert(pst);
pst->_a = malloc(sizeof(STDataType) * 4);
pst->_top = 0;
pst->_capacity = 4;
}
void StackDestory(Stack* pst)
{
assert(pst);
free(pst->_a);
pst->_a = NULL;
pst->_capacity = pst->_top = 0;
}
//入栈
void StackPush(Stack* pst, STDataType x)
{
assert(pst);
//增容问题
//realloc()函数的使用条件是在已经创建出的内存下进行修改内存的操作
//TDataType* temp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
if (pst->_top == pst->_capacity)
{
pst->_capacity *= 2;
STDataType* tmp = (STDataType*)realloc(pst->_a, sizeof(STDataType) * pst->_capacity);
if (tmp == NULL)
{
printf("内存不足\n");
exit(-1);
}
else
{
pst->_a = tmp;
}
}
pst->_a[pst->_top] = x;
pst->_top++;
}
//出栈(正确)
void StackPop(Stack* pst)
{
assert(pst);
assert(pst->_top > 0);
--pst->_top;
}
//获取栈的个数(正确)
int StackSize(Stack* pst)
{
assert(pst);
return pst->_top;
}
//判断栈是否为空,为空返回1,不为空返回0(正确)
int StackEmpty(Stack* pst)
{
assert(pst);
return pst->_top == 0 ? 1 : 0;
}
//获取栈顶的数据,首先要确保栈顶是有数据的
STDataType StackTop(Stack* pst)
{
assert(pst);
assert(pst->_top > 0);
return pst->_a[pst->_top - 1];
}
typedef struct {
Stack _pushST;
Stack _popST;
} MyQueue;
//创建栈初始化返回
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&q->_popST);
StackInit(&q->_pushST);
return q;
}
//入栈
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->_pushST, x);
}
//出栈并删除
int myQueuePop(MyQueue* obj) {
int front = myQueuePeek(obj);
StackPop(&obj->_popST);
return front;
}
//出栈且数据不动
int myQueuePeek(MyQueue* obj) {
if (!StackEmpty(&obj->_popST))
{
return StackTop(&obj->_popST);
}
else
{
while (!StackEmpty(&obj->_pushST))
{
StackPush(&obj->_popST, StackTop(&obj->_pushST));
StackPop(&obj->_pushST);
}
return StackTop(&obj->_popST);
}
}
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->_popST) && StackEmpty(&obj->_pushST);
}
void myQueueFree(MyQueue* obj) {
StackDestory(&obj->_popST);
StackDestory(&obj->_pushST);
free(obj);
}
/**
* Your MyQueue struct will be instantiated and called as such:
* MyQueue* obj = myQueueCreate();
* myQueuePush(obj, x);
* int param_2 = myQueuePop(obj);
* int param_3 = myQueuePeek(obj);
* bool param_4 = myQueueEmpty(obj);
* myQueueFree(obj);
*/
解析:
(1)引用栈的源代码
代码过长见答案
题目是用栈实现队列,这里我们可以使用我们自己栈的接口来进行实现更为好操作
(2)定义两个栈,_push和_pop,两者可以倒换进而达到实现队列先进先出的作用
typedef struct {
Stack _pushST;
Stack _popST;
} MyQueue;
---->
1)向push中依次储存1,2,3,4
2)通过将push的值由栈的后进先出的逻辑由4到1分别进入pop中
3)pop中top值依次取出符合队列先进先出的逻辑
(3)创建栈并初始化后返回
MyQueue* myQueueCreate() {
MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&q->_popST);
StackInit(&q->_pushST);
return q;
}
初始化开辟空间q
初始化_popST和_pushST
返回q
(4)使用自己接口实现储存数据至_pushST中
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->_pushST, x);
}
调用自己的接口用指针obj访问_push将数据x储存
(5)出队列且数据不删除
int myQueuePeek(MyQueue* obj) {
if (!StackEmpty(&obj->_popST))
{
return StackTop(&obj->_popST);
}
else
{
while (!StackEmpty(&obj->_pushST))
{
StackPush(&obj->_popST, StackTop(&obj->_pushST));
StackPop(&obj->_pushST);
}
return StackTop(&obj->_popST);
}
}
由于这是一个出队列接口所以我们无法确定popST中是否由数据,然而popST中数据符合逻辑上队列先进先出的逻辑,故我们可以直接使用接口StackTop()读取栈的顶端值并使用return进行返回
(6)判断是队列是否为空
bool myQueueEmpty(MyQueue* obj) {
return StackEmpty(&obj->_popST) && StackEmpty(&obj->_pushST);
}
首先当且仅当两个栈_popST _pushST都为空时,队列中才没有数据,才为空,故这里我们可以使用&&通过我们自己的接口StackEmpty()函数来进行判断为空则返回1
当并且运算符当且仅当1&&1时运算结果为1,其余情况皆是0,由于是bool类型的值,return 1为ture,reutrn 0为false
(7)释放队列
void myQueueFree(MyQueue* obj) {
StackDestory(&obj->_popST);
StackDestory(&obj->_pushST);
free(obj);
}
这里我们使用自己的接口StackDestory()来摧毁两个栈并且释放obj
到这里我们解题完毕
如果对您有帮助的话点一个免费的赞和收藏叭!
由于本人水平不足,如果有任何错误,麻烦读者评论在评论区指点一下作者,谢谢