队列是一种 先进先出(first in - first out, FIFO)的数据结构,队列中的元素都从后端(rear)入队(push),从前端(front)出队(pop)。

实现队列最直观的方法是用链表,但在这篇文章里我会介绍另一个方法 - 使用栈。

栈是一种 后进先出(last in - first out, LIFO)的数据结构,栈中元素从栈顶(top)压入(push),也从栈顶弹出(pop)。

为了满足队列的 FIFO 的特性,我们需要用到两个栈,用它们其中一个来反转元素的入队顺序,用另一个来存储元素的最终顺序。

方法一(使用两个栈 入队 - O(n)O(n), 出队 - O(1)O(1))

算法

入队(push)思路:考虑入队的元素是先进先出,后进后出,而你的栈是后进先出,那么你最新压入的元素(后进的)应该在栈底,也就是只要保证后进后出即可

一个队列是 FIFO 的,但一个栈是 LIFO 的。这就意味着最新压入的元素必须得放在栈底。为了实现这个目的,我们首先需要把 s1 中所有的元素移到 s2 中,接着把新元素压入 s2。最后把 s2 中所有的元素弹出,再把弹出的元素压入 s1。

出队(pop)

直接从 s1 弹出就可以了,因为 s1 的栈顶元素就是队列的队首元素。同时我们把弹出之后 s1 的栈顶元素赋值给代表队首元素的 front 变量。

以上图片以及文字来自https://leetcode-cn.com/problems/implement-queue-using-stacks/solution/yong-zhan-shi-xian-dui-lie-by-leetcode/

#include

#include

#define maxsize 100

//创建栈

struct Stack{

int data[maxsize];

int top;

};

typedef struct Stack MyStack;

//队列定义为双栈

typedef struct {

MyStack s1; //S1为主栈

MyStack s2; //S2为用来反转的栈

} MyQueue;

/** Initialize your data structure here. */

MyQueue* myQueueCreate() {

MyQueue * tempQueue =(MyQueue *)malloc(sizeof(MyQueue));

tempQueue->s1.top = -1 ;

tempQueue->s2.top = -1 ;

return tempQueue ;

}

/** Push element x to the back of queue. */

void myQueuePush(MyQueue* obj, int x) {

if(obj->s1.top

{

while(obj->s1.top!=-1) //栈是否满

{

obj->s2.data[++(obj->s2.top)]=obj->s1.data[(obj->s1.top)--];把S1栈中元素压入S2实现反转

}

obj->s1.data[++(obj->s1.top)]= x ; 把push的元素压入S1栈(此时S1为空栈,因为它的元素已经全部给S2啦)

while(obj->s2.top!=-1)

{

obj->s1.data[++(obj->s1.top)]=obj->s2.data[(obj->s2.top)--];//再把S2栈中的元素全部反转压入S1

}

}

}

void show_myQueue(MyQueue * obj)

{

int temp =obj->s1.top ;

while(temp!=-1)

{

printf("%d ",obj->s1.data[temp--]);

}

printf("\n");

}

/** Removes the element from in front of queue and returns that element. */

int myQueuePop(MyQueue* obj) {

if(obj->s1.top!=-1)

{

return obj->s1.data[obj->s1.top--] ;

}

// return NULL ;

}

/** Get the front element. */

int myQueuePeek(MyQueue* obj) {

if(obj->s1.top!=-1)

{

return obj->s1.data[obj->s1.top] ;

}

// return NULL ;

}

/** Returns whether the queue is empty. */

bool myQueueEmpty(MyQueue* obj) {

if(obj->s1.top == -1)

return true ;

return false ;

}

void myQueueFree(MyQueue* obj) {

free(obj);

}

int main()

{

int i ;

MyQueue * myQueue =NULL;

myQueue =myQueueCreate();

for(i=0;i<3;i++)

{

myQueuePush(myQueue,i);

}

show_myQueue(myQueue);

printf("出队的元素是:%d\n",myQueuePop(myQueue));

printf("此时队列内的首个的元素是:%d\n",myQueuePeek(myQueue));

}

/**

* Your MyQueue struct will be instantiated and called as such:

* MyQueue* obj = myQueueCreate();

* myQueuePush(obj, x);

* int param_2 = myQueuePop(obj);

* int param_3 = myQueuePeek(obj);

* bool param_4 = myQueueEmpty(obj);

* myQueueFree(obj);

*/

c语言Inqueue函数用法,C语言用两个栈实现队列(完整版)相关推荐

  1. c语言pow函数用法_C语言基础的不能再基础的程序知识!“hello world”!

    涉及到的知识点有:include有两种用法.{}大括号用法解释.C语言自定义名字的要求. c语言库函数printf的解释.编译错误有两种.调用system函数.c语言编译过程. 操作系统结构.指令集中 ...

  2. c 语言void函数用法,c语言void的用法

    许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误.下面小编就跟大家介绍下c语言void的用法. c语言void的用法1.void的含义 void的字面意思是 ...

  3. linux中c语言kbhit函数用法,C语言判断用户是否输入-非阻塞函数kbhit

    一.基础研究 要从地址读取数据,肯定是要定义一个指针变量p,用它来实现变换地址和取值的功能.另外程序是当两个条件中的某一个出现时才停止,所以应该用while~do循环语句循环输出n和d,并用while ...

  4. c语言memset函数用法,C语言memset函数使用方法详解

    C语言memset函数使用方法详解 一.函数原形   void *  memset(void*s, int ch,size_t n) 二.函数作用  将以s内存地址为首的连续n个字节的内容置成ch,一 ...

  5. c语言malloc函数用法_C语言内存模型!小本本记起来啊!

    一.C语言的内存分配模型 1.程序代码区:存放函数体的二进制代码. 2.全局区数据区:全局数据区划分为三个区域.全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全 ...

  6. c语言strtof函数用法,c语言工具函数

    abort abs assert atexit atof atoi atol atoll bsearch div exit _Exit getenv labs llabs ldiv lldiv lon ...

  7. r语言qsignrank函数用法_R语言常用函数名

    一.数据管理 vector:向量 numeric:数值型向量 logical:逻辑型向量 character:字符型向量 list:列表 data.frame:数据框 c:连接为向量或列表 lengt ...

  8. C语言atoi()函数用法

    C语言atoi()函数用法 头文件:#include <stdlib.h> atoi() 函数用来将字符串转换成整数(int),其原型为: int atoi (const char * s ...

  9. fclose在c语言中的作用,c语言fcloseall函数用法实例介绍

    c语言fcloseall函数用法实例介绍.fcloseall函数的返回值,函数 fcloseall() 将所有打开的流与其底层的文件或功能集合关闭.任何缓冲的数据都将首先被写入,使用 fflush(3 ...

最新文章

  1. My github blog
  2. [转帖] 固定硬盘接口 U.2和M.2
  3. transfer = C only read dynamically - why it fails to work
  4. 指针应用时的注意事项
  5. FFmpeg学习(0)——使用ffmpeg视频切片并加密
  6. MATLAB求解分段函数
  7. Terrasolid安装
  8. 用Python中的VTK库导入并显示Assembly的STL文件
  9. 实验二 帧中继的基本配置
  10. 基于C++的深度学习模型部署
  11. windows 平台shellcode编写
  12. db2 ? 22018
  13. Java开发一个登陆窗体,包括用户名,密码以及提交按钮和重置按钮,当用户输入amy,密码123456,弹出登陆成功提示对话框
  14. python qrcode生成彩色二维码
  15. JAVA面试题100道一
  16. flask-项目结构
  17. 网易互娱将星N计划空宣 要点速记
  18. 智方6000系标准销售管理系统 v4.57 绿色
  19. Unity3dRPG 相机跟随player旋转_「Facebook」应用程序Bug会悄悄访问相机,发紧急声明会修复且更新...
  20. 电子通信类顶级会议及期刊1(自用更新版)

热门文章

  1. 无人驾驶技术--五个等级
  2. 【kissfft】使用过程中的一些坑总结
  3. 【Kaldi安装问题】Nvidia库cub安下载失败
  4. MariaDB/MySQL防止重复插入相同记录:INSERT IGNORE或者REPLACE
  5. 小学生计算机课堂实践的重要性,多媒体在小学教学中的重要性
  6. 贪吃蛇程序 php,php,函数 Web程序 - 贪吃蛇学院-专业IT技术平台
  7. jdbcpingquery mysql_JDBC - liuping - 博客园
  8. cs go linux 参数,CSGO 命令大全 给新手的福利 使用设置参数
  9. php中短信验证大致流程,实现php手机短信验证功能的基本思路
  10. php array的实现原理,PHP数组遍历与实现原理