http://blog.csdn.net/z84616995z/article/details/19204529

两个栈实现一个队列:

原理方法:用一个栈为主栈,一个栈为辅助栈存放临时元素。

入队:将元素依次压入主栈

出队:先检测辅助栈是否为空,如果非空,那么直接弹出辅助栈顶元素,相当于出队。如果为空,那么将主栈元素倒入到辅助栈中,然后弹出辅助栈顶元素。达到先进先出的目的。

以下是代码:

[cpp] view plain copy
  1. //两个个栈实现一个队列
  2. /*#include <iostream>
  3. #include <time.h>
  4. #include <windows.h>
  5. using namespace std;
  6. #define MAX 10
  7. struct stack
  8. {
  9. int Array[MAX];
  10. int top;
  11. };
  12. struct stack s1,s2;
  13. //初始化一个空栈
  14. int Init_Stack()
  15. {
  16. s1.top=s2.top = -1;//top为-1表示空栈
  17. return 1;
  18. }
  19. //入队
  20. void enqueue(int Array[],int x)
  21. {
  22. if (s1.top==MAX-1)//检测是否栈已满
  23. {
  24. cout<<"overflow!"<<endl;
  25. }
  26. else
  27. {
  28. s1.top++;
  29. s1.Array[s1.top]=x;//将元素压入主栈
  30. }
  31. }
  32. //出队
  33. int dequeue()
  34. {
  35. if (s1.top==-1&&s2.top==-1)//如果主栈和辅助栈都是空的,那么就出现下溢。提示错误后返回
  36. {
  37. cout<<"underflow!"<<endl;
  38. return -1;
  39. }
  40. if (s2.top==-1)//如果辅助栈为空,那么就循环地将主栈元素倒入辅助栈
  41. {
  42. for (int i=s1.top;i>0;i--)
  43. {
  44. s1.top--;s2.top++;
  45. s2.Array[s2.top]=s1.Array[s1.top+1];
  46. }
  47. s1.top--;
  48. return s1.Array[s1.top+1];//返回主栈最后一个元素作为出队元素
  49. }
  50. else //如果辅助栈不空,那么直接弹出辅助栈栈顶元素作为出队元素
  51. {
  52. s2.top--;
  53. return s2.Array[s2.top+1];
  54. }
  55. }
  56. void main()
  57. {
  58. int x=0;
  59. Init_Stack();
  60. srand( (unsigned)time( NULL ) );
  61. cout<<"数组中的数据入队中。。。";
  62. for( int j=0; j <= 100; j++ )      // 打印百分比
  63. {
  64. cout.width(3);
  65. cout << j << "%";
  66. Sleep(40);
  67. cout << "\b\b\b\b";//\b退格符号
  68. }
  69. cout << "\n\n";
  70. cout<<"Array=";
  71. for (int i=0;i<MAX;i++)
  72. {
  73. x=rand()%100;
  74. cout<<x<<" ";
  75. enqueue(s1.Array,x);
  76. }
  77. cout<<endl;
  78. cout<<"所有数据入队完毕!"<<endl;
  79. cout<<endl;
  80. cout<<"数组中的数据出队中。。。";
  81. for(  j=0; j <= 100; j++ )      // 打印百分比
  82. {
  83. cout.width(3);
  84. cout << j << "%";
  85. Sleep(40);
  86. cout << "\b\b\b\b";//\b退格符号
  87. }
  88. cout << "\n\n";
  89. cout<<"Array=";
  90. for ( i=0;i<MAX;i++)
  91. {
  92. cout<<dequeue()<<" ";
  93. }
  94. cout<<endl;
  95. cout<<"所有数据出队完毕!"<<endl;
  96. cout<<endl;
  97. enqueue(s1.Array, 56);
  98. cout<<dequeue()<<endl;
  99. cout<<dequeue()<<endl;
  100. cout<<dequeue()<<endl;
  101. enqueue(s1.Array, 65);
  102. enqueue(s1.Array, 10);
  103. enqueue(s1.Array, 32);
  104. cout<<dequeue()<<endl;
  105. cout<<dequeue()<<endl;
  106. enqueue(s1.Array, 2);
  107. cout<<dequeue()<<endl;
  108. }

运行时间为O(n),在进行倒入操作时需要循环倒入,所以时间为n

两个队列实现一个栈:

原理方法:用一个队列为主队列,一个队列为辅助队列存放临时元素。

入栈:将元素依次压入主队列

出栈:先将拥有n个元素的主队列的其中的n-1个元素倒入辅助队列,然后将原主队列的最后剩下的一个元素弹出队列,相当于出栈,这个时候,辅助队列和主队列进行交换,继续进行刚才的出栈操作。

[cpp] view plain copy
  1. //两个队列实现一个栈
  2. #include <iostream>
  3. #include <time.h>
  4. #include <windows.h>
  5. using namespace std;
  6. #define MAX 10
  7. struct queue
  8. {
  9. int head;//声明队头指针
  10. int tail;//声明队尾指针
  11. int length;//声明队列当前含有的元素个数
  12. int Array[MAX];//声明数组所能容纳的最大元素个数
  13. };
  14. struct queue q1,q2; //声明两个队列结构体全局变量
  15. void Init_queue(struct queue &q1)//初始化队列
  16. {
  17. q1.head=q1.tail=1;//队列初始时是从数组Array[1]开始的,所以其实Array[0]是数组最后一个元素,而不是Array[MAX-1]!这是需要注意的。
  18. q1.length=1;
  19. }
  20. //入栈
  21. int push(int Array[],int x)
  22. {
  23. if (q1.head==q1.tail+1)//进行入队操作的前提判断是否队列已满
  24. {
  25. cerr<<"overflow!"<<endl;//若已满,那么提示错误后返回。
  26. return -1;
  27. }
  28. else
  29. {
  30. if (q1.length==0)//恢复队列中没有元素时的初始值q1.length=1;
  31. {
  32. q1.length++;q2.length++;
  33. }
  34. q1.length++;q2.length++;//每次入队数组元素个数+1
  35. if (q1.tail==q1.length)//队尾指针既然已经指向当前数组最后一个元素的下一个位置
  36. {
  37. q1.tail=0;//那么元素只能插入Array[0]最后一个元素,原因在Init_queue函数注释中。
  38. q1.Array[q1.tail]=x;
  39. }
  40. else
  41. {
  42. q1.Array[q1.tail]=x;
  43. q1.tail++;
  44. if (q1.tail==MAX)//若队尾指针指向数组最后一个元素的下一个位置
  45. {
  46. q1.length--;q2.length--;//由于两个队列元素个数是从1开始的,那么主和辅助队列元素个数已经超过MAX,所以需要调整为MAX,以便下次入队时插入到Array[0]这个位置
  47. }
  48. }
  49. return q1.tail;
  50. }
  51. }
  52. //出栈
  53. int pop()
  54. {
  55. int x=0;
  56. if (q1.length<=0)//如果主队列里面有0个元素,那么说明不能进行出队(出栈)操作,直接返回错误提示
  57. {
  58. cerr<<"underflow"<<endl;
  59. return -1;
  60. }
  61. else
  62. {
  63. if (q1.tail==0)//通常情况需要返回的是队头指针作为出队元素,那么这里为什么返回队尾指针?因为我们需要用两个队列实现一个栈,那么有n个元素的主栈,把n-1个元素传递给辅助队列后,最后入队的也是将要出栈的元素肯定在主栈队尾。
  64. {
  65. x=q1.Array[q1.tail];//队尾指针指向0时(其实指向的就是数组最后一位,因为初始化是从1开始的),直接返回Array[0]
  66. }
  67. else
  68. {
  69. x=q1.Array[q1.tail-1];//队尾指针指向其它时,由于队尾指针总是指向数组最后一个数据的下一位,那么需要返回的是数组最后一个数据,所以要-1.
  70. }
  71. while(q1.tail!=q1.head)//队头和队尾相等时,说明已经遍历了整个队列,所以退出循环
  72. {
  73. q2.Array[q2.tail]=q1.Array[q1.head];//将主栈的数据传递给辅助栈
  74. if (q2.tail==MAX)//由于需要循环遍历队列,所以当队尾等于数组所能容纳的最大元素个数时,队尾指针自动调整到数组第一个位置。
  75. {
  76. q2.tail=0;
  77. }
  78. else
  79. {
  80. q2.tail++;
  81. }
  82. if (q1.head==MAX)//和上面的if-else类似。
  83. {
  84. q1.head=0;
  85. }
  86. else
  87. {
  88. q1.head++;
  89. }
  90. }
  91. if (q1.tail==0)//如果队尾指针等于0,自动指向当前主队列的最后一个元素的下一个位置
  92. {
  93. q1.tail=q1.length;//这样在下次出队时能够返回队列的最后一个元素。
  94. }
  95. else
  96. {
  97. q1.tail--;//如果队尾指针不等于0,那么当前主队列队尾下标指向下一个需要出队的元素。
  98. }
  99. swap(q1,q2);//原来的主队列转换为辅助队列,原来的辅助队列转换为主队列。
  100. q1.tail=q2.tail;//由于转换后,原主队列队尾下标变为辅助队列队尾下标,所以需要将当前辅助队列队尾下标传递给主队列
  101. q2.head=q2.tail=1;//辅助队列里的元素个数保持不变,然后其指针恢复为初始状态。由于辅助队列只是起到一个临时保存队列中数据的作用,所以每次主队列有元素出队,就需要初始化辅助队列一下。
  102. q1.length--;q2.length--;//每次出队后,需要将辅助和主队列当前拥有的元素个数-1.
  103. return x;//主队列队尾元素出队(相当于出栈)
  104. }
  105. }
  106. void swap(struct queue &q1,struct queue &q2)//辅助队列与主队列之间转换
  107. {
  108. struct queue temp;
  109. temp=q1;
  110. q1=q2;
  111. q2=temp;
  112. }
  113. void main()
  114. {
  115. int x=0;
  116. Init_queue(q1);
  117. Init_queue(q2);
  118. srand( (unsigned)time( NULL ) );
  119. cout<<"数组中的数据入栈中。。。";
  120. for( int j=0; j <= 100; j++ )      // 这个循环就是一个看起来很酷的小程序,其实实际作用没有。^_^
  121. {
  122. cout.width(3);
  123. cout << j << "%";
  124. Sleep(40);
  125. cout << "\b\b\b\b";//\b退格符号
  126. }
  127. cout << "\n\n";
  128. cout<<"Array=";
  129. for (int i=0;i<MAX;i++)//对于开始q1和q2两个空栈来说,设置q1为主栈,q2为辅助栈
  130. {
  131. x=rand()%100;
  132. int t=push(q1.Array,x);
  133. if (t==-1)//既然队列已满,那么提示不能入栈后,自动跳出循环。
  134. {
  135. break;
  136. }
  137. if (q1.tail==0)
  138. {
  139. cout<<q1.Array[q1.tail]<<" ";
  140. }
  141. else
  142. {
  143. cout<<q1.Array[q1.tail-1]<<" ";
  144. }
  145. }
  146. cout<<endl;
  147. cout<<"所有数据入栈完毕!"<<endl;
  148. cout<<endl;
  149. cout<<"数组中的数据出栈中。。。";
  150. for(  j=0; j <= 100; j++ )      // 打印百分比
  151. {
  152. cout.width(3);
  153. cout << j << "%";
  154. Sleep(40);
  155. cout << "\b\b\b\b";//\b退格符号
  156. }
  157. cout << "\n\n";
  158. cout<<"Array=";
  159. for ( i=0;i<MAX;i++)
  160. {
  161. cout<<pop()<<" ";
  162. }
  163. cout<<endl;
  164. cout<<"所有数据出栈完毕!"<<endl;
  165. cout<<endl;
  166. }

运行时间:由于需要将主队列循环倒入到辅助队列中,所以总时间为O(n).

两个栈实现一个队列与两个队列实现一个栈相关推荐

  1. 两个栈实现一个队列,两个队列实现一个栈

    题目:用两个栈实现一个队列,用两个队列实现一个栈. 首先要了解栈和队列这两种数据结构各自的特点,栈是一种后入先出(Last In First Out,LIFO)的数据结构,队列是一种先进先出(Firs ...

  2. 栈与队列2——两个栈组成队列

    题目 编写一个类,用两个栈实现一个队列,并实现队列的基本操作(add,poll,peek) 思路 一个栈stackPush作为正常压入的栈,一个栈stackPop作为弹出的栈,将stackPush中的 ...

  3. 两个栈实现队列与两个队列实现栈

    1. 两个栈实现队列 实现一 思路 s1是入栈的,s2是出栈的. 入队列,直接压到s1是就行了 出队列,先把s1中的元素全部出栈压入到s2中,弹出s2中的栈顶元素:再把s2的所有元素全部压回s1中 实 ...

  4. C#数据结构:两栈实现队列,两队列实现栈

    两个栈实现队列:栈实现先进先出 栈1负责队尾,栈2负责队头 每次入队,栈2无元素且栈1无元素,入栈2:否则入栈1 每次出队,栈2有元素,出栈2顶:否则把全部栈1入栈2,再出栈2顶 bool Pop(r ...

  5. 两顺序栈共享Java_数据结构与算法(三),栈与队列

    上一篇<数据结构与算法(二),线性表>中介绍了数据结构中线性表的两种不同实现--顺序表与链表.这一篇主要介绍线性表中比较特殊的两种数据结构--栈与队列.首先必须明确一点,栈和队列都是线性表 ...

  6. 一个数组实现两个栈(共享栈)

    题目:   一个数组实现两个栈. 方法1:   下标为0的位置为栈1的栈底,下标为1的位置为栈2的栈底,栈1的元素存放在下标为偶数的位置上,栈2的元素放在下标为奇数的位置上.   如上图所示的数组:若 ...

  7. 算法与数据结构题目的 PHP 实现:栈和队列 由两个栈组成的队列

    思路:同样使用 PHP 的数组模拟栈.栈的特点是先进后出,队列的特点是先进先出,可以用第一个栈(StackPush)作为压入栈,压入数据的时候只往这个栈中压入数据,第二个栈作(StackPop)为弹出 ...

  8. 栈顶指针和队尾指针指向当前位置和指向下一个位置的区别?——轻松搞懂栈和队列指针的指向问题

    我们先看一下队列的队尾指针指向队尾元素的当前位置的入队操作: 可以看到,当队尾指针指向的是队尾元素时,我想加入一个新的元素,这时直接放在队尾指向的位置是不可以的,因为这个位置已经有元素了,所以先要对队 ...

  9. 【学校实验】停车场问题:设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。

    停车场问题 问题描述 测试数据 基本要求 实现提示 代码实现 栈的实现 队列的实现 主函数的实现 问题描述 设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出.汽车在停车场内按车辆 ...

最新文章

  1. jdbc mysql连接测试_JDBC测试计划-连接mysql
  2. 实训09.10:HTML简单表格设计
  3. java +号变空格_base64码通过http传输 +号变 空格 问题解决
  4. Python3 爬虫实战 — 豆瓣电影TOP250【requests、Xpath、正则表达式、CSV、二进制数据储存】
  5. 请写出sfr和sbit的语句格式_习题_C51语言答案
  6. 一次失败的蛋疼的设计
  7. 雷军 1994 年写的代码,你见过吗?厉害了!
  8. 【STM32】HAL库 STM32CubeMX教程十四---SPI
  9. ubuntu16.04 虚拟机装机后常用操作
  10. hibernate执行完查询操作后又执行许多更新操作
  11. iis 缓存 静态文件_强制更新IIS中的缓存JavaScript文件
  12. 极客学院HTML5全套教程
  13. SSM整合案例分析(详解)
  14. 项目一:认识Linux操作系统
  15. sql中模糊查询的字段中包含百分号%的语句
  16. char **和char* []区别,char *和char []区别
  17. 3.软碟通制作Linux安装盘
  18. php接收参数引号带斜杆
  19. 浏览器中左键点击网页标签为何突然自动关闭?
  20. elementUI中的el-table勾选框设置默认勾选、禁用

热门文章

  1. @Resource和@Autowired作用和区别
  2. TCP/IP三次握手与四次握手
  3. 工作总结:文件对话框的分类(C++)
  4. 华为鸿蒙手机beta版,鸿蒙2.0 Beta手机版来了!明年将全面支持华为手机
  5. php 字符串与数字相加,注意!PHP中字符串与数字的比较
  6. am82.top 1.php,Droppy v2.1.3 – PHP在线网盘系统
  7. 仪器和软件通讯测试软件,软件定义的仪器-测试测量-与非网
  8. netapp管理地址_NetApp常用管理命令总结
  9. java婚庆网站源码_基于jsp的婚庆网站-JavaEE实现婚庆网站 - java项目源码
  10. php树莓派魔镜,用树莓派和显示器制作一面“魔镜”