一、用对列实现栈
题干要求:
细节分析:队列是先进先出; 要实现的栈是先进后出。
解题思路:假设:先用一个队列储存数据 n 个,然后将前 n-1 个数据导入到另一个队列,
此时,原始队列中仅剩一个,是最后剩的数据,便可将其导出,这便是一次后进先出。
细节点:每次导出数据时,都需要一个队列向另一个队列传入数据,因此输入队列和输出队列 需要轮换,要对其进行判定。
具体过程gif动态图如下:
代码实现
1.初始化栈:先初始化两个队列
//栈的结构是由两个队列构成 typedef struct nystack{ quetail q1; quetail q2; } mystack; //栈的初始化 mystack* mystackcreate() { mystack* newstack = (mystack*)malloc(sizeof(mystack)); que_init(&newstack->q1); que_init(&newstack->q2); return newstack; }
2. 插入数据
因为存储数据的队列不是固定的,因此在一个队列有数据的前提下,就继续向该队列插入数据,
空的队列负责在导出数据时进行轮转。(哪个不空向哪个插入)
//插入数据 void mystackpush(mystack* obj, int x) { //if((&obj->q1)->head == null) //法一:直接判断是否为空 if(que_empty(&obj->q1)) //法二:后续函数的复用 que_push(&obj->q2,x); else que_push(&obj->q1,x); }
3.导出数据(实现先进后出)
第一步:将有数据的队列中除最后进的数据,依次导入到另一个空队列 ;
导入空队列,删除原队列,保留最后数据。
第二布:将原队列中最后一个数据导出 。
注:这里先假设了两个队列中,一个是原队列和一个是空队列,再进行判定,若与实际不符,则 交换 。
int mystackpop(mystack* obj) { int temp = 0; //假设原队列和空队列 quetail* existque = &obj->q1,*nullque = &obj->q2; if((&obj->q1)->head == null) //判断与实际是否相符 { existque = nullque; nullque = &obj->q1; } for(;existque->head->next;) //保留最后一个数据 { que_push(nullque,existque->head->data); //向空队列导入数据 que_pop(existque); //删除原队列数据 } temp = existque->head->data; que_pop(existque); //导出最后进的数据 return temp; }
4.查找栈顶数据
找到不空的队列 >> 返回其队尾的数据
int mystacktop(mystack* obj) { if((&obj->q1)->head == null) { return (&obj->q2)->tail->data; } return (&obj->q1)->tail->data; }
5.判断栈是否为空:
判断两个队列是否均为空
bool mystackempty(mystack* obj) { assert(obj); //法一:直接判断 //if((&obj->q1)->head == null&& (&obj->q2)->head == null) //法二:复用队列判空函数 if(que_empty(&(obj->q1))&&que_empty(&(obj->q2))) return true; return false; }
6.销毁栈:
销毁两个队列
void mystackfree(mystack* obj) { que_destory(&obj->q1); que_destory(&obj->q2); free(obj); }
二、用栈实现队列
题干要求:
细节分析:这次是用两个栈,实现先进先出 。
解题思路:首先,将两个栈分为入口栈和出口栈,
其次,数据正序入口栈,由于栈是先进后出,因此将数据再逆序进入出口栈,
然后,此时数据再出口栈中是逆序,所以,便可以正序从出口栈中依次排出 。
代码实现
1.初始化双栈队列
typedef struct { stack t1; stack t2; } myqueue; myqueue* myqueuecreate() { myqueue *q1; q1 = (myqueue*)malloc(sizeof(myqueue)); stack_init(&(q1->t1)); // t1 做入口栈 stack_init(&(q1->t2)); // t2 做出口栈 return q1; }
2.插入数据
void myqueuepush(myqueue* obj, int x) { stack_push(&obj->t1,x); //这里将栈 t1 作为入口栈 }
3.删除数据(先进先出)
将入口栈数据记录 >> 删除入口栈数据 >> 导入出口栈 >> 从出口栈导出数据
int myqueuepop(myqueue* obj) { if(stack_empty(&obj->t2)) //判断是否为空 { int k = 0; for(;!stack_empty(&obj->t1);) { k = stack_top(&obj->t1); //记录入口站数据 stack_pop(&obj->t1); //删除入口栈数据 stack_push(&obj->t2,k); //导入出口栈 } } int temp = 0; temp = stack_top(&obj->t2); stack_pop(&obj->t2); //从出口栈导出数据 return temp; //题干要求返回导出的值 }
4.查找队列头部数据
这里的头部数据是正序的头数据,因此要先将入口栈中的逆序数据导入出口栈,
变成正序,再返回出口栈的栈顶数据 。
int myqueuepeek(myqueue* obj) { if(stack_empty(&obj->t2)) //判断出口栈中是否有数据 { int k = 0; for(;!stack_empty(&obj->t1);) //向出口栈导入数据 { k = stack_top(&obj->t1); stack_pop(&obj->t1); stack_push(&obj->t2,k); } } return stack_top(&obj->t2); //返回出口栈栈顶数据 }
5.判断队列是否为空 及 销毁队列
//判断队列是否为空 bool myqueueempty(myqueue* obj) { //判断两个栈是否均为空 return stack_empty(&obj->t1)&&stack_empty(&obj->t2); } //销毁释放队列 void myqueuefree(myqueue* obj) { stack_pop(&obj->t1); stack_pop(&obj->t2); free(obj); }
以上就是c语言数据结构之栈与队列的相互实现的详细内容,更多关于c语言 栈 队列的资料请关注<计算机技术网(www.ctvol.com)!!>其它相关文章!
需要了解更多c/c++开发分享C语言数据结构之栈与队列的相互实现,都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/1120955.html