用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/

由于C语言的栈要自己实现。前面写好栈的一些接口,代码在最后。

思路:双栈。

先说两个栈的作用:一个栈用于插入,一个栈用于删除。

1.创建队列,两个栈即可。假定s1用于插入,s2用于删除

将两个栈初始化好。

2.尾插,直接在s1里面插入就可以。

3.尾删。由于队列的先进先出的,因此要借助s2来删除。

基本逻辑是:当要删除时,把s1里的元素pop出来,然后push到s2里面。直到s1为空,此时s2的top就是队列的头部,也就是要删除的元素。

在移动数据时,这里有四种情况,每一种都考虑好就行了。

  1. s1和s2都是空
  2. s1为空,s2不为空
  3. s1不为空,s2为空
  4. s1和s2都不为空

s1和s2都是空
直接返回-1即可,因为整个队列都是空了。

s1为空,s2不为空
这种情况就是没有把原先的元素全部pop完的情况,直接pop s2的top就可以了。
s1不为空,s2为空
这就是还没开始删的时候,直接把s1的元素全部倒到s2,然后pop s2的top就可以了。

两个都不是空
这种形况发生在:刚把s1里面的元素push到s2进行删除后,立刻push了元素。

初始状态:

push元素到s1后:

这是以队列的视角来看就是

6 5 4 3 2 1--------->5 4 3 2 1-------->5 4 3 2 1 1
因此直接pop s2的top就可以了。

可以总结一下:
四种情况中 s1为空,s2不为空和两个都不是空的代码是一样的,其他两种情况单独写就好了。

代码(大部分都是实现栈的接口):

#include <stdio.h>
#include <stdbool.h>
#include <malloc.h>
#include <assert.h>
typedef int StackDataType;typedef struct stack
{StackDataType* a;//dynamicint top;int capacity;
}stack;void StackInit(stack* p);
void stackDestroy(stack* p);
void stackPush(stack* p, StackDataType x);
void stackPop(stack* p);
StackDataType stackTop(stack* p);
int stackSize(stack* p);
bool stackEmpty(stack* p);void StackInit(stack* p)
{p->a = (StackDataType*)malloc(sizeof(StackDataType) * 4);p->top = 0;p->capacity = 4;
}void stackDestroy(stack* p)
{free(p->a);p->capacity = p->top = 0;p->a = NULL;p = NULL;
}void stackPush(stack* p, StackDataType x)
{assert(p);if (p->capacity == p->top){p->capacity *= 2;p->a = (StackDataType*)realloc(p->a, sizeof(StackDataType) * p->capacity);if (p == NULL){printf("realloc fail");exit(-1);}}p->a[p->top++] = x;
}void stackPop(stack* p)
{assert(p);p->top--;
}StackDataType stackTop(stack* p)
{assert(p);return p->a[p->top - 1];
}int stackSize(stack* p)
{return p->top;
}bool stackEmpty(stack* p)
{return p->top == 0;
}typedef struct {stack s1;stack s2;
} CQueue;CQueue* cQueueCreate() {CQueue* obj = (CQueue*)malloc(sizeof(stack)*2);StackInit(&(obj->s1));StackInit(&(obj->s2));return obj;
}void cQueueAppendTail(CQueue* obj, int value) {stackPush(&obj->s1,value);
}int cQueueDeleteHead(CQueue* obj) {//把四种情况都罗列出来就可以了。if(stackEmpty(&obj->s1)&&stackEmpty(&obj->s2))//两个都是空return -1;if(stackEmpty(&obj->s2))//如果s2是空{while(!stackEmpty(&obj->s1)){stackPush(&obj->s2,stackTop(&obj->s1));stackPop(&obj->s1);}printf("1\n");int top = stackTop(&obj->s2);stackPop(&obj->s2);return top;}if(!stackEmpty(&obj->s2) && stackEmpty(&obj->s1))//如果s2不是空且s1是空{printf("2\n");int top = stackTop(&obj->s2);stackPop(&obj->s2);return top;}if(!stackEmpty(&obj->s1)&&!stackEmpty(&obj->s2))//两个都不是空{int top = stackTop(&obj->s2);stackPop(&obj->s2);return top;}return -1;
}void cQueueFree(CQueue* obj) {stackDestroy(&obj->s1);stackDestroy(&obj->s2);free(obj);obj = NULL;
}

用两个栈实现队列(C语言版)相关推荐

  1. c++ 队列_Day 5:用两个栈实现队列

    剑指Offer_编程题--用两个栈实现队列 题目描述: 用两个栈来实现一个队列,完成队列的push和pop操作.队列中的元素为int类型 具体要求: 时间限制: C/C++ 1秒,其他语言2秒 空间限 ...

  2. 剑指offer:面试题09. 用两个栈实现队列

    题目:用两个栈实现队列 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能.(若队列中没有 ...

  3. 剑指offer_第5题_用两个栈实现队列

    题目描述 用两个栈来实现一个队列 完成队列的Push和Pop操作 队列中的元素为int类型 理解 关于栈 什么是栈 栈的抽象数据类型 Python实现栈 关于队列 什么是队列 队列抽象数据类型 Pyt ...

  4. 《LeetCode力扣练习》剑指 Offer 09. 用两个栈实现队列 Java

    <LeetCode力扣练习>剑指 Offer 09. 用两个栈实现队列 Java 一.资源 题目: 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 appendTail 和 de ...

  5. 剑指Offer #05 用两个栈实现队列(模拟)

    题目来源:牛客网-剑指Offer专题 题目地址:用两个栈实现队列 题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 题目解析 首先,我们需要知道一下基本知 ...

  6. 【干货】容器适配器实现两个栈模拟队列

    用两个栈模拟队列的思想就是"倒水思想",这里我们用自定义类型模拟出线性表,再用线性表做容器实现栈的数据结构,最后用栈来实现队列,代码如下: #include<iostream ...

  7. 剑指offer第二版-9.用两个栈实现队列

    描述:使用两个栈实现一个队列.队列中实现尾部插入和头部删除函数. 思路:stack1负责插入,stack2负责弹出,如果stack2为空了,将stack1的元素依次弹出并存放到stack2中,之后对s ...

  8. 《剑指offer》-- 构建乘积数组、求1+2+3+...+n、不用加减乘除做加法、包含min函数的栈、用两个栈实现队列

    一.构建乘积数组: 1.题目: 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*. ...

  9. 《剑指offer》第九题(用两个栈实现队列)

    // 面试题:用两个栈实现队列 // 题目:用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail // 和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的 ...

  10. 栈一:用两个栈实现队列

    /**  * 题目:用两个栈实现队列  * 描述:用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型.  * 解决方案:方法一:一个作为存储用,一个作为弹出用  * * ...

最新文章

  1. linux7设置时间,CentOS 7 设置日期和时间
  2. 数据通信技术(十一:无中继的DHCP配置(ZTE))
  3. JavaScript闭包原理与用法实例
  4. redis、memcache、mongoDB 对比
  5. 我的新宠Vue a系列 项目初构
  6. vsCode 设置vue 保存自动格式化代码
  7. linux查找当前目录下所有子目录特定文件类型
  8. javascript : spket 视频教程
  9. C++ isalpha、isalnum、islower、isupper、tolower、toupper用法
  10. 【已解决】U盘文件误删 恢复,实用有效 免费无充值 Recuva
  11. linux文件误删恢复解决方案
  12. matlab中clc什么意思,MATLAB中clc是什么意思
  13. 【ARM汇编】打印金字塔 | 打印倒三角
  14. 力扣-无重复字符的最长子串
  15. 如何在 Python 中构建跨平台桌面应用程序
  16. MacOS系统升级与MacOS13版本
  17. MySQL日期和时间函数 整理
  18. CDN在前端开发中的作用
  19. 计算机cast函数是什么意思,CAST()函数
  20. 超大容量充电宝哪个好,大容量移动充电宝哪个品牌好?

热门文章

  1. 计算机简单公文,[计算机]常用公文写作方法.doc
  2. 推荐系统热门研究方向
  3. 软考网络工程师怎么学习,用那些书籍?
  4. flash builder对代码进行调试 下载flash player debug软件
  5. DELL设备维保查询方法
  6. e3mall Day06
  7. 碰到国内外虚拟机无法识别usb加密狗或者银行U盾问题,大家请进入!!!
  8. SAP/PP-40策略下SO不消耗PIR问题
  9. 【Linux】使用阿里yum源,解决yum下载过慢的问题
  10. 你不可能知道的骨架屏玩法!