赞
踩
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作**(push、pop、peek、empty)**:
实现 MyQueue 类:
- void push(int x) 将元素 x 推到队列的末尾
- int pop() 从队列的开头移除并返回元素
- int peek() 返回队列开头的元素
- boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:
- 你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
- 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
这里挂上题目链接: 232.用栈实现队列
这道题目其实就是让我们用栈的基本功能以及函数实现队列的基本功能及函数
- myQueueCreate - 创建MyQueue
- myQueuePush - MyQueue入队
- myQueuePop - MyQueue出队
- myQueuePeek - MyQueue取队头
- myQueueEmpty - MyQueue判空
- myQueueFree - myQueue释放
比较重要的一点就是我们使用C实现,所以我们需要先手搓一遍栈的函数才能写这道题(当然完全理解过栈和队列的话CV一下也不是不行(doge))
我们都知道,如果给一串数据,全部入栈之后再出栈,出栈的数据的顺序会反过来,而题目要求我们使用两个栈实现队列,我们就可以利用上进栈再出栈会逆置的特性
这里我们在 MyQueue 结构体里定义两个分别指向 栈st1 和 栈st2 的指针
//定义MyQueue
typedef struct
{
ST* st1;
ST* st2;
} MyQueue;
MyQueue* pmq = (MyQueue*)calloc(1, sizeof(MyQueue));
pmq->st1 = NULL;
pmq->st2 = NULL;
pmq->st1 = (ST*)calloc(1, sizeof(ST));
pmq->st2 = (ST*)calloc(1, sizeof(ST));
STInit(pmq->st1);
STInit(pmq->st2);
return pmq;
所以 myQueueCreate 函数就长这样
//创建MyQueue
MyQueue* myQueueCreate()
{
MyQueue* pmq = (MyQueue*)calloc(1, sizeof(MyQueue));
pmq->st1 = NULL;
pmq->st2 = NULL;
pmq->st1 = (ST*)calloc(1, sizeof(ST));
pmq->st2 = (ST*)calloc(1, sizeof(ST));
STInit(pmq->st1);
STInit(pmq->st2);
return pmq;
}
//MyQueue入队
void myQueuePush(MyQueue* obj, int x)
{
STPush(obj->st1, x);
}
while(!STEmpty(obj->st1))
{
STPush(obj->st2, STTop(obj->st1));
STPop(obj->st1);
}
int ret = STTop(obj->st2);
STPop(obj->st2);
while(!STEmpty(obj->st2))
{
STPush(obj->st1, STTop(obj->st2));
STPop(obj->st2);
}
return ret;
那么这就是 MyQueue 的一次完整的"出队"了
//MyQueue出队 int myQueuePop(MyQueue* obj) { while(!STEmpty(obj->st1)) { STPush(obj->st2, STTop(obj->st1)); STPop(obj->st1); } int ret = STTop(obj->st2); STPop(obj->st2); while(!STEmpty(obj->st2)) { STPush(obj->st1, STTop(obj->st2)); STPop(obj->st2); } return ret; }
"取队头"的步骤其实和"出队"差不多,只是中间少了一步让 st2 栈顶出栈的内容,也就导致我只是取了 st2栈顶 的值而已, 取完值之后 st2 里的内容全都原封不动地还给 st1 了
一样的把 st1 的所有值入一遍 st2
while(!STEmpty(obj->st1))
{
STPush(obj->st2, STTop(obj->st1));
STPop(obj->st1);
}
int ret = STTop(obj->st2);
while(!STEmpty(obj->st2))
{
STPush(obj->st1, STTop(obj->st2));
STPop(obj->st2);
}
return ret;
以下是MyQueue取队头的完整代码
//MyQueue取队头 int myQueuePeek(MyQueue* obj) { while(!STEmpty(obj->st1)) { STPush(obj->st2, STTop(obj->st1)); STPop(obj->st1); } int ret = STTop(obj->st2); while(!STEmpty(obj->st2)) { STPush(obj->st1, STTop(obj->st2)); STPop(obj->st2); } return ret; }
//MyQueue判空
bool myQueueEmpty(MyQueue* obj)
{
return STEmpty(obj->st1);
}
//MyQueue释放
void myQueueFree(MyQueue* obj)
{
STDestroy(obj->st1);
STDestroy(obj->st2);
obj->st1 = NULL;
obj->st2 = NULL;
free(obj);
}
- 区别于思路1,思路2不需要频繁让数据在 st1 和 st2 之间来回跳
- 一样的让 st1 专注"入队", st2 专注"出队",区别在于要等 st2 "出队"完才向其补充数据
- 其他的函数就如法炮制就行了,这里着重讲取"队头"和"出队"
//MyQueue取队头
int myQueuePeek(MyQueue* obj)
{
if(STEmpty(obj->st2))//判断 st2 有没有数据,有数据就不动,没数据就把 st1 的数据挪过来
{
while(!STEmpty(obj->st1))
{
STPush(obj->st2, STTop(obj->st1));
STPop(obj->st1);
}
}
int ret = STTop(obj->st2);
return ret;
}
- 注意:这里动画先执行了三次出队,然后执行了一次入队,最后执行了三次出队
//MyQueue出队
int myQueuePop(MyQueue* obj)
{
if(STEmpty(obj->st2))//判断 st2 有没有数据,有数据就不动,没数据就把 st1 的数据挪过来
{
while(!STEmpty(obj->st1))
{
STPush(obj->st2, STTop(obj->st1));
STPop(obj->st1);
}
}
int ret = STTop(obj->st2);
STPop(obj->st2);
return ret;
}
因为这里是用C写这道题,所以代码前面一定得加上栈的所有内容哦
//类型定义 typedef int DataType; typedef struct stack { DataType* pdata; int top; int capa; }ST; //函数定义 //栈的扩容 void CheckCapa(ST* pst); //获取栈顶数据 DataType STTop(ST* pst); //栈的判空 bool STEmpty(ST* pst); //查看数据量 int STSize(ST* pst); //栈的初始化 void STInit(ST* pst); //栈的删除 void STDestroy(ST* pst); //压栈 void STPush(ST* pst, DataType data); //出栈 void STPop(ST* pst); //函数定义 //栈的扩容 void CheckCapa(ST* pst) { assert(pst); if (pst->top + 1 == pst->capa) { DataType* tmp = (DataType*)realloc(pst->pdata, 2 * pst->capa * sizeof(DataType)); if (tmp == NULL) { perror("CheckCapa::realloc"); exit(1); } else { pst->pdata = tmp; } pst->capa = 2 * pst->capa; } } //获取栈顶数据 DataType STTop(ST* pst) { assert(pst); return pst->pdata[pst->top]; } //栈的判空 bool STEmpty(ST* pst) { assert(pst); return pst->top + 1 == 0; } //查看数据量 int STSize(ST* pst) { assert(pst); return pst->top + 1; } //栈的初始化 void STInit(ST* pst) { assert(pst); pst->pdata = (DataType*)calloc(4, sizeof(DataType)); if (pst->pdata == NULL) { perror("STInit::calloc"); exit(1); } pst->top = -1; pst->capa = 4; } //栈的删除 void STDestroy(ST* pst) { free(pst->pdata); pst->pdata = NULL; pst->capa = 0; pst->top = -1; } //压栈 void STPush(ST* pst, DataType data) { CheckCapa(pst); (pst->top)++; pst->pdata[pst->top] = data; } //出栈 void STPop(ST* pst) { if (STEmpty(pst)) { return; } else { (pst->top)--; } } //---------------------------------------------------------------------------------------------------- //定义MyQueue typedef struct { ST* st1; ST* st2; } MyQueue; //创建MyQueue MyQueue* myQueueCreate() { MyQueue* pmq = (MyQueue*)calloc(1, sizeof(MyQueue)); pmq->st1 = NULL; pmq->st2 = NULL; pmq->st1 = (ST*)calloc(1, sizeof(ST)); pmq->st2 = (ST*)calloc(1, sizeof(ST)); STInit(pmq->st1); STInit(pmq->st2); return pmq; } //MyQueue入队 void myQueuePush(MyQueue* obj, int x) { STPush(obj->st1, x); } //MyQueue出队 int myQueuePop(MyQueue* obj) { while(!STEmpty(obj->st1)) { STPush(obj->st2, STTop(obj->st1)); STPop(obj->st1); } int ret = STTop(obj->st2); STPop(obj->st2); while(!STEmpty(obj->st2)) { STPush(obj->st1, STTop(obj->st2)); STPop(obj->st2); } return ret; } //MyQueue取队头 int myQueuePeek(MyQueue* obj) { while(!STEmpty(obj->st1)) { STPush(obj->st2, STTop(obj->st1)); STPop(obj->st1); } int ret = STTop(obj->st2); while(!STEmpty(obj->st2)) { STPush(obj->st1, STTop(obj->st2)); STPop(obj->st2); } return ret; } //MyQueue判空 bool myQueueEmpty(MyQueue* obj) { return STEmpty(obj->st1); } //MyQueue释放 void myQueueFree(MyQueue* obj) { STDestroy(obj->st1); STDestroy(obj->st2); obj->st1 = NULL; obj->st2 = NULL; free(obj); }
typedef int DataType; typedef struct stack { DataType* pdata; int top; int capa; }ST; //函数定义 //栈的扩容 void CheckCapa(ST* pst); //获取栈顶数据 DataType STTop(ST* pst); //栈的判空 bool STEmpty(ST* pst); //查看数据量 int STSize(ST* pst); //栈的初始化 void STInit(ST* pst); //栈的删除 void STDestroy(ST* pst); //压栈 void STPush(ST* pst, DataType data); //出栈 void STPop(ST* pst); //函数定义 //栈的扩容 void CheckCapa(ST* pst) { assert(pst); if (pst->top + 1 == pst->capa) { DataType* tmp = (DataType*)realloc(pst->pdata, 2 * pst->capa * sizeof(DataType)); if (tmp == NULL) { perror("CheckCapa::realloc"); exit(1); } else { pst->pdata = tmp; } pst->capa = 2 * pst->capa; } } //获取栈顶数据 DataType STTop(ST* pst) { assert(pst); return pst->pdata[pst->top]; } //栈的判空 bool STEmpty(ST* pst) { assert(pst); return pst->top + 1 == 0; } //查看数据量 int STSize(ST* pst) { assert(pst); return pst->top + 1; } //栈的初始化 void STInit(ST* pst) { assert(pst); pst->pdata = (DataType*)calloc(4, sizeof(DataType)); if (pst->pdata == NULL) { perror("STInit::calloc"); exit(1); } pst->top = -1; pst->capa = 4; } //栈的删除 void STDestroy(ST* pst) { free(pst->pdata); pst->pdata = NULL; pst->capa = 0; pst->top = -1; } //压栈 void STPush(ST* pst, DataType data) { CheckCapa(pst); (pst->top)++; pst->pdata[pst->top] = data; } //出栈 void STPop(ST* pst) { if (STEmpty(pst)) { return; } else { (pst->top)--; } } //---------------------------------------------------------------------------------------------------- //定义MyQueue typedef struct { ST* st1; ST* st2; } MyQueue; //创建MyQueue MyQueue* myQueueCreate() { MyQueue* pmq = (MyQueue*)calloc(1, sizeof(MyQueue)); pmq->st1 = NULL; pmq->st2 = NULL; pmq->st1 = (ST*)calloc(1, sizeof(ST)); pmq->st2 = (ST*)calloc(1, sizeof(ST)); STInit(pmq->st1); STInit(pmq->st2); return pmq; } //MyQueue入队 void myQueuePush(MyQueue* obj, int x) { STPush(obj->st1, x); } //MyQueue出队 int myQueuePop(MyQueue* obj) { if(STEmpty(obj->st2)) { while(!STEmpty(obj->st1)) { STPush(obj->st2, STTop(obj->st1)); STPop(obj->st1); } } int ret = STTop(obj->st2); STPop(obj->st2); return ret; } //MyQueue取队头 int myQueuePeek(MyQueue* obj) { if(STEmpty(obj->st2)) { while(!STEmpty(obj->st1)) { STPush(obj->st2, STTop(obj->st1)); STPop(obj->st1); } } int ret = STTop(obj->st2); return ret; } //MyQueue判空 bool myQueueEmpty(MyQueue* obj) { return (STEmpty(obj->st1) && STEmpty(obj->st2)); } //MyQueue释放 void myQueueFree(MyQueue* obj) { STDestroy(obj->st1); STDestroy(obj->st2); obj->st1 = NULL; obj->st2 = NULL; free(obj); }
佬!都看到这了,如果觉得有帮助的话一定要点赞啊佬 >v< !!!
放个卡密在这,感谢各位能看到这儿啦!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。