1.思路解析
首先了解,队列遵循先进先出,栈遵循后进先出,所以利用两个栈popst与pushst进行元素转移后可以实现先进先出的功能。原题来源于leetcode中的:232.用队列实现栈
2.操作详解
首先要自己写一个栈及其操作,这里直接给出,详情请移步到我的另一篇文章:暴力数据结构之栈与队列(栈的相关操作)
源码如下:
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
// 初始化和销毁
void STInit(ST* pst)
{
assert(pst);
pst->a = NULL;
// top指向栈顶数据的下一个位置
pst->top = 0;
// top指向栈顶数据
//pst->top = -1;
pst->capacity = 0;
}
void STDestroy(ST* pst)
{
assert(pst);
free(pst->a);
pst->a = NULL;
pst->top = pst->capacity = 0;
}
// 入栈 出栈
void STPush(ST* pst, STDataType x)
{
assert(pst);
// 扩容
if (pst->top == pst->capacity)
{
int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
return;
}
pst->a = tmp;
pst->capacity = newcapacity;
}
pst->a[pst->top] = x;
pst->top++;
}
void STPop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
pst->top--;
}
// 取栈顶数据
STDataType STTop(ST* pst)
{
assert(pst);
assert(pst->top > 0);
return pst->a[pst->top - 1];
}
// 判空
bool STEmpty(ST* pst)
{
assert(pst);
return pst->top == 0;
}
// 获取数据个数
int STSize(ST* pst)
{
assert(pst);
return pst->top;
}
2.1 创建与释放
首先创建两个栈,进行动态内存申请后使用先前给出源码中的初始化函数。
typedef struct
{
ST popst;
ST pushst;
} MyQueue;
MyQueue* myQueueCreate()
{
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
STInit(&(obj->popst));
STInit(&(obj->pushst));
return obj;
}
释放要注意先释放"小弟"obj->pushst和obj->popst,然后释放"大哥"obj,防止内存泄漏
void myQueueFree(MyQueue* obj)
{
STDestroy(&(obj->pushst));
STDestroy(&(obj->popst));
free(obj);
}
2.2 返回队列开头元素
当栈popst不为空时直接返回栈顶元素即可,若为空就将另一个栈pushst中的元素取出后插入popst中,最后返回popst的栈顶元素。不为空的示意图如下:
int myQueuePeek(MyQueue* obj)
{
if(STEmpty(&(obj->popst)))
{
while(!STEmpty(&(obj->pushst)))
{
int top = STTop(&(obj->pushst));
STPush(&(obj->popst),top);
STPop(&(obj->pushst));
}
}
return STTop(&(obj->popst));
}
2.3 插入与删除
插入:直接调用插入函数即可。
void myQueuePush(MyQueue* obj, int x)
{
STPush(&(obj->pushst),x);
}
删除:找到栈顶元素,直接利用前面的peek即可,至于是否为空交给peek判断即可,然后删除
int myQueuePop(MyQueue* obj)
{
int front = myQueuePeek((obj));
STPop(&(obj->popst));
return front;
}
2.4 判空
判空:两个栈均为空才为空,直接返回其值即可
bool myQueueEmpty(MyQueue* obj)
{
return STEmpty(&(obj->pushst)) && STEmpty(&(obj->popst));
}