• I 用c l 栈与队列的相互实现


    目录

    一、用对列实现栈

     二、用栈实现队列


    一、用对列实现栈

    题干要求:

     

     

    细节分析:队列是先进先出; 要实现的栈是先进后出。

    解题思路:假设:先用一个队列储存数据 N 个,然后将前 N-1 个数据导入到另一个队列,

                     此时,原始队列中仅剩一个,是最后剩的数据,便可将其导出,这便是一次后进先出。

    细节点   :每次导出数据时,都需要一个队列向另一个队列传入数据,因此输入队列和输出队列                    需要轮换,要对其进行判定。

    具体过程gif动态图如下:

     

    代码实现:

    1.初始化栈:先初始化两个队列

    1. //栈的结构是由两个队列构成
    2. typedef struct Nystack{
    3. Quetail q1;
    4. Quetail q2;
    5. } MyStack;
    6. //栈的初始化
    7. MyStack* myStackCreate() {
    8. MyStack* Newstack = (MyStack*)malloc(sizeof(MyStack));
    9. Que_Init(&Newstack->q1);
    10. Que_Init(&Newstack->q2);
    11. return Newstack;
    12. }

    2. 插入数据

    因为存储数据的队列不是固定的,因此在一个队列有数据的前提下,就继续向该队列插入数据,

    空的队列负责在导出数据时进行轮转。(哪个不空向哪个插入)

    1. //插入数据
    2. void myStackPush(MyStack* obj, int x) {
    3. //if((&obj->q1)->head == NULL) //法一:直接判断是否为空
    4. if(Que_Empty(&obj->q1)) //法二:后续函数的复用
    5. Que_push(&obj->q2,x);
    6. else
    7. Que_push(&obj->q1,x);
    8. }

    3.导出数据(实现先进后出)

      

    第一步:将有数据的队列中除最后进的数据,依次导入到另一个空队列 ;

                  导入空队列,删除原队列,保留最后数据。

    第二布:将原队列中最后一个数据导出 。

    注:这里先假设了两个队列中,一个是原队列和一个是空队列,再进行判定,若与实际不符,则          交换 。

    1. int myStackPop(MyStack* obj) {
    2. int temp = 0;
    3. //假设原队列和空队列
    4. Quetail* existque = &obj->q1,*nullque = &obj->q2;
    5. if((&obj->q1)->head == NULL) //判断与实际是否相符
    6. {
    7. existque = nullque;
    8. nullque = &obj->q1;
    9. }
    10. for(;existque->head->Next;) //保留最后一个数据
    11. {
    12. Que_push(nullque,existque->head->data); //向空队列导入数据
    13. Que_pop(existque); //删除原队列数据
    14. }
    15. temp = existque->head->data;
    16. Que_pop(existque); //导出最后进的数据
    17. return temp;
    18. }

    4.查找栈顶数据   

    找到不空的队列 >> 返回其队尾的数据

    1. int myStackTop(MyStack* obj) {
    2. if((&obj->q1)->head == NULL)
    3. {
    4. return (&obj->q2)->tail->data;
    5. }
    6. return (&obj->q1)->tail->data;
    7. }

    5.判断栈是否为空:

    判断两个队列是否均为空

    1. bool myStackEmpty(MyStack* obj) {
    2. assert(obj);
    3. //法一:直接判断
    4. //if((&obj->q1)->head == NULL&& (&obj->q2)->head == NULL)
    5. //法二:复用队列判空函数
    6. if(Que_Empty(&(obj->q1))&&Que_Empty(&(obj->q2)))
    7. return true;
    8. return false;
    9. }

    6.销毁栈:

    销毁两个队列

    1. void myStackFree(MyStack* obj) {
    2. Que_Destory(&obj->q1);
    3. Que_Destory(&obj->q2);
    4. free(obj);
    5. }

     二、用栈实现队列

    题干要求: 

     

     细节分析:这次是用两个栈,实现先进先出 。

    解题思路:首先,将两个栈分为入口栈和出口栈,

                     其次,数据正序入口栈,由于栈是先进后出,因此将数据再逆序进入出口栈,

                     然后,此时数据再出口栈中是逆序,所以,便可以正序从出口栈中依次排出 。

     

    代码实现:

    1.初始化双栈队列

    1. typedef struct {
    2. Stack T1;
    3. Stack T2;
    4. } MyQueue;
    5. MyQueue* myQueueCreate() {
    6. MyQueue *Q1;
    7. Q1 = (MyQueue*)malloc(sizeof(MyQueue));
    8. Stack_init(&(Q1->T1)); // T1 做入口栈
    9. Stack_init(&(Q1->T2)); // T2 做出口栈
    10. return Q1;
    11. }

    2.插入数据

    1. void myQueuePush(MyQueue* obj, int x) {
    2. Stack_push(&obj->T1,x); //这里将栈 T1 作为入口栈
    3. }

     3.删除数据(先进先出)

    将入口栈数据记录 >> 删除入口栈数据 >> 导入出口栈 >> 从出口栈导出数据

     

    1. int myQueuePop(MyQueue* obj) {
    2. if(Stack_Empty(&obj->T2)) //判断是否为空
    3. {
    4. int k = 0;
    5. for(;!Stack_Empty(&obj->T1);)
    6. {
    7. k = Stack_Top(&obj->T1); //记录入口站数据
    8. Stack_pop(&obj->T1); //删除入口栈数据
    9. Stack_push(&obj->T2,k); //导入出口栈
    10. }
    11. }
    12. int temp = 0;
    13. temp = Stack_Top(&obj->T2);
    14. Stack_pop(&obj->T2); //从出口栈导出数据
    15. return temp; //题干要求返回导出的值
    16. }

     4.查找队列头部数据

        这里的头部数据是正序的头数据,因此要先将入口栈中的逆序数据导入出口栈,

        变成正序,再返回出口栈的栈顶数据 。

    1. int myQueuePeek(MyQueue* obj) {
    2. if(Stack_Empty(&obj->T2)) //判断出口栈中是否有数据
    3. {
    4. int k = 0;
    5. for(;!Stack_Empty(&obj->T1);) //向出口栈导入数据
    6. {
    7. k = Stack_Top(&obj->T1);
    8. Stack_pop(&obj->T1);
    9. Stack_push(&obj->T2,k);
    10. }
    11. }
    12. return Stack_Top(&obj->T2); //返回出口栈栈顶数据
    13. }

    5.判断队列是否为空 及 销毁队列

    1. //判断队列是否为空
    2. bool myQueueEmpty(MyQueue* obj) {
    3. //判断两个栈是否均为空
    4. return Stack_Empty(&obj->T1)&&Stack_Empty(&obj->T2);
    5. }
    6. //销毁释放队列
    7. void myQueueFree(MyQueue* obj) {
    8. Stack_pop(&obj->T1);
    9. Stack_pop(&obj->T2);
    10. free(obj);
    11. }

    感谢大家的支持!!! 

     

     

     

     

     

     

  • 相关阅读:
    含磷废水的处理方法
    【RRT三维路径规划】基于matlab快速扩展随机树无人机三维路径规划【含Matlab源码 1914期】
    busybox命令裁剪
    58同城登录如何免验证码,通过账号登录,有的联系我
    面试官:了解HashSet吗?请做下面的题目
    canal部署、原理和使用介绍
    算法导论笔记5:贪心算法
    MyBatis篇---第三篇
    Python 基于 urllib 使用 Handler 处理器(代理)
    第五话、离职前被老板威胁是一种什么样的体验
  • 原文地址:https://blog.csdn.net/MT_125/article/details/125593163