双栈模拟队列与双队列模拟栈

1.两个队列共享一个环形向量空间,将这两个队列模拟成栈,并实现十进制转化为二进制

程序如下:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #define maxSize 20
  4 typedef int DataType;
  5 typedef struct
  6 {
  7     DataType elem[maxSize];
  8     int front[2],rear[2];
  9 }DualQueue;
 10 void InitQueue(DualQueue *Q)
 11 {
 12     Q->front[0]=Q->rear[0]=0;
 13     Q->front[1]=Q->rear[1]=maxSize/2;
 14 }
 15 int EnQueue(DualQueue *Q,DataType x,int flag)
 16 {
 17     if(flag<0||flag>1)
 18     {
 19         return 0;
 20     }
 21     if(Q->front[flag]==Q->rear[1-flag])
 22     {
 23         if(Q->front[1-flag]==Q->rear[flag]) //假设另一个队列也满
 24         {
 25             return 0;
 26         }
 27         //不满则将另一个队列向前挪动一位置
 28         for(int i=Q->rear[1-flag];i!=Q->front[1-flag];i=(i-1)%maxSize)
 29         {
 30             Q->elem[(i+1)%maxSize]=Q->elem[i-1];
 31         }
 32         Q->rear[1-flag]=(Q->rear[1-flag]+1)%maxSize;
 33         Q->front[1-flag]=(Q->front[1-flag]+1)%maxSize;
 34
 35         Q->rear[flag]=(Q->rear[flag]+1)%maxSize;
 36         Q->elem[Q->rear[flag]]=x;
 37         return 1;
 38     }
 39     Q->rear[flag]=(Q->rear[flag]+1)%maxSize;
 40     Q->elem[Q->rear[flag]]=x;
 41     return 1;
 42 }
 43 int DeQueue(DualQueue *Q,DataType *x,int flag)
 44 {
 45     if(flag<0||flag>1)
 46     {
 47         return 0;
 48     }
 49     if(Q->front[flag]==Q->rear[flag])
 50     {
 51         return 0;
 52     }
 53     Q->front[flag]=(Q->front[flag]+1)%maxSize;
 54     *x=Q->elem[Q->front[flag]];
 55     return 1;
 56 }
 57 void QStackInit(DualQueue *Q)
 58 {
 59     InitQueue(Q);
 60 }
 61 bool QStackEmpty(DualQueue *Q)
 62 {
 63     if(Q->front[0]==Q->rear[0]&&Q->front[1]==Q->rear[1])
 64     {
 65         return true;
 66     }
 67     else
 68     {
 69         return false;
 70     }
 71 }
 72 bool QStackFull(DualQueue *Q)
 73 {
 74     if(Q->front[0]==Q->rear[1]&&Q->front[1]==Q->rear[0])
 75     {
 76         return true;
 77     }
 78     else
 79     {
 80         return false;
 81     }
 82 }
 83 bool QStackPush(DualQueue *Q,int x)
 84 {
 85     if(QStackFull(Q))
 86     {
 87         return false;
 88     }
 89     if(QStackEmpty(Q))
 90     {
 91         EnQueue(Q,x,0);
 92     }
 93     else if(!(Q->front[0]==Q->rear[0]))
 94     {
 95         EnQueue(Q,x,0);
 96     }
 97     else
 98     {
 99         EnQueue(Q,x,1);
100     }
101     return true;
102 }
103 bool QStackPop(DualQueue *Q,int *x)
104 {
105     if(QStackEmpty(Q))
106     {
107         return false;
108     }
109     if(!(Q->front[0]==Q->rear[0]))
110     {
111         while(1)
112         {
113             DeQueue(Q,x,0);
114             if(!(Q->front[0]==Q->rear[0]))
115             {
116                 EnQueue(Q,*x,1);
117             }
118             else
119             {
120                 break;
121             }
122         }
123     }
124     else
125     {
126         while(1)
127         {
128             DeQueue(Q,x,1);
129             if(!(Q->front[1]==Q->rear[1]))
130             {
131                 EnQueue(Q,*x,0);
132             }
133             else
134             {
135                 break;
136             }
137         }
138     }
139     return true;
140 }
141 int main()
142 {
143     DualQueue Q;
144     QStackInit(&Q);
145     int x,i,result=0;
146     printf("请输入一个十进制数:\n");
147     scanf("%d",&x);
148     while(x!=0)
149     {
150         i=x%2;
151         x=x/2;
152         QStackPush(&Q,i);
153     }
154     while(!QStackEmpty(&Q))
155     {
156         QStackPop(&Q,&i);
157         result=result*10+i;
158     }
159     printf("二进制为:%d\n",result);
160 } 

运行结果如下:

在此程序中,应注意如果一个队列满了,而另一个队列未满,则可以移动元素位置,改变队列空间,与栈浮动技术相似。同时在挪动位置的过程中,循环控制条件不应设为>,而应该为!=。

2.使用两栈模拟一个队列,并实现输出杨辉三角

程序如下:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 typedef int SElemType;
  4 typedef struct node
  5 {
  6     SElemType data;
  7     struct node *link;
  8 }LinkNode,*LinkStack;
  9 void StackInit(LinkStack *S)
 10 {
 11     (*S)=NULL;
 12 }
 13 int StackEmpty(LinkStack *S)
 14 {
 15     return (*S)==NULL;
 16 }
 17 int StackPush(LinkStack *S,SElemType x)
 18 {
 19     LinkNode *p=(LinkNode *)malloc(sizeof(LinkNode));
 20     p->data=x;
 21     p->link=(*S);
 22     (*S)=p;
 23     return 1;
 24 }
 25 int StackPop(LinkStack *S,SElemType *x)
 26 {
 27     if(S==NULL)
 28     {
 29         return 0;
 30     }
 31     LinkNode *p=(*S);
 32     *x=p->data;
 33     (*S)=p->link;
 34     free(p);
 35     return 1;
 36 }
 37 void SQueueInit(LinkStack *S1,LinkStack *S2)
 38 {
 39     StackInit(S1);
 40     StackInit(S2);
 41 }
 42 bool SQueueEmpty(LinkStack *S1,LinkStack *S2)
 43 {
 44     if(StackEmpty(S1)&&StackEmpty(S2))
 45     {
 46         return true;
 47     }
 48     return false;
 49 }
 50 int EnSQueue(LinkStack *S1,LinkStack *S2,int x)
 51 {
 52     if(SQueueEmpty(S1,S2))
 53     {
 54         StackPush(S1,x);
 55     }
 56     else if(!StackEmpty(S1))
 57     {
 58         StackPush(S1,x);
 59     }
 60     else
 61     {
 62         StackPush(S2,x);
 63     }
 64     return 1;
 65 }
 66 int DeSQueue(LinkStack *S1,LinkStack *S2,int *x)
 67 {
 68     if(SQueueEmpty(S1,S2))
 69     {
 70         return 0;
 71     }
 72     if(!StackEmpty(S1))
 73     {
 74         while(1)
 75         {
 76             StackPop(S1,x);
 77             if(!StackEmpty(S1))
 78             {
 79                 StackPush(S2,*x);
 80             }
 81             else
 82             {
 83                 break;
 84             }
 85         }
 86         int temp;
 87         while(1)
 88         {
 89             StackPop(S2,&temp);
 90             StackPush(S1,temp);
 91             if(StackEmpty(S2))
 92             {
 93                 break;
 94             }
 95         }
 96     }
 97     else
 98     {
 99         while(1)
100         {
101             StackPop(S2,x);
102             if(!StackEmpty(S2))
103             {
104                 StackPush(S1,*x);
105             }
106             else
107             {
108                 break;
109             }
110         }
111         int temp;
112         while(1)
113         {
114             StackPop(S1,&temp);
115             StackPush(S2,temp);
116             if(StackEmpty(S1))
117             {
118                 break;
119             }
120         }
121     }
122 }
123 void YangHvi(int n)
124 {
125     LinkStack S1,S2;
126     SQueueInit(&S1,&S2);
127     EnSQueue(&S1,&S2,1);
128     EnSQueue(&S1,&S2,1);
129     int i,j;
130     int s=0,t;
131     for(int i=1;i<=n;i++)
132     {
133         printf("\n");
134         EnSQueue(&S1,&S2,0);
135         for(int j=i;j<=n-1;j++)
136         {
137             printf("%2c",‘ ‘);
138         }
139         for(int j=1;j<=i+2;j++)
140         {
141             DeSQueue(&S1,&S2,&t);
142             EnSQueue(&S1,&S2,s+t);
143             s=t;
144             if(j!=i+2)
145             {
146                 printf("%4d",s);
147             }
148         }
149     }
150 }
151 main()
152 {
153     int n;
154     printf("请输入行数:\n");
155     scanf("%d",&n);
156     YangHvi(n);
157 }

运行结果如下:

在此程序中应注意的是,模拟队列与模拟栈的细微区别(仅依据这两个程序而言):输入元素基本一样,输出元素,在模拟栈中还多了一步,将栈1的元素(除最后一个元素)全部传给栈2,然后输出元素,最后还需要将栈2的全部元素又传回给栈1.

原文地址:https://www.cnblogs.com/duwenze/p/10803991.html

时间: 2024-10-08 02:24:14

双栈模拟队列与双队列模拟栈的相关文章

自定义栈的实现及使用两个栈模拟队列

一,使用单链表实现栈 ①栈需要一个栈顶指针 ②栈的基本操作有出栈和入栈,以及判断栈是否为空 ③单链表中每个结点表示一个栈元素,每个结点有指向下一个结点的指针.因此,在栈内部需要实现一个单链表.代码如下: public class Stack<T extends Comparable<? super T>>{ private class Node{ T ele; Node next; public Node(T ele) { this.ele = ele; } } Node top;

数据结构和算法之栈和队列一:两个栈模拟一个队列以及两个队列模拟一个栈

今天我们需要学习的是关于数据结构里面经常看到的两种结构,栈和队列.可以说我们是一直都在使用栈,比如说在前面递归所使用的的系统的栈,以及在链表倒序输出时介绍的自定义栈类Stack和使用系统的栈进行递归.那么,在这里我们就讲述一下这两个比较具有特色的或者说关系比较紧密的数据结构之间的互相实现问题. 一:两个栈模拟实现一个队列: 栈的特点是先进后出,然而队列的特点是先进先出. public class Queen(Stack s1,Stack s2){ //实现插入的方法 public void ad

《面试题精选》16.双栈实现队列和双队列实现栈

题目:分别用两个栈实现一个队列,和两个队列实现一个栈 分析: 1> 两个栈实现一个队列: 首先我们还是老方法,举个少量数据的例子,从中发现规律.首先我们向其中一个栈中插入a,b,c.存入栈中的顺序就是c-b-a,此时我们如果进行dequeue操作的话,因为队列是先进先出,所以a是先出的,但如果我们直接对栈pop的话那么出来的就是c.所以我们要将栈1中的数据转移到栈2中,直到最后一个元素时则把它出栈.这样我们就完成了dequeue操作. 但是queue操作怎么办?比如我们要让e,f入队,还是跟前面

用LinkedList模拟一个堆栈或者队列数据结构 总结: LinkedList知识点

/** 用LinkedList模拟一个堆栈或者队列数据结构. 创建一个堆栈和队列数据结构对象,该对象中使用LinkedList来完成的. 知识点总结: 1.LinkedList特点:链表式数据结构. 重复有序,查询速度慢,增删速度快.不同步的. 2.LinkedList除了实现List接口增删改查的功能外,有一些特有的方法,能够实现在List(列表)的开头和结尾 插入,删除,获取等特有功能.这就是为什么LinkedList能够模拟一个堆栈,或者队列,双端队列的数据结构了. 涉及知识点: 1.什么

PHP双向队列,双端队列代码

<?php /**  * User: jifei  * Date: 2013-07-30  * Time: 23:12 */ /**  * PHP实现双向队列,双端队列  * 双端队列(deque,全名double-ended queue)是一种具有队列和栈性质的数据结构.  * 双端队列中的元素可以从两端弹出,插入和删除操作限定在队列的两边进行.  */ class Deque {     public $queue=array();     /**      * 构造函数初始化队列     

从0开始学算法--数据结构(2.4双端队列与单调队列)

双端队列是特殊的队列,它与队列不同的是可以将元素加入头或尾,可以从头或尾取出元素(滑稽-这部就是栈和队列结合了吗). c++标准库 头文件 #include<deque> 定义 deque<int>deq; 取出队头,尾元素 deq.pop_front(); deq.pop_back(); 访问队头,尾元素 deq.front(); deq.back(); 向队头,尾加入元素 deq.push_front(x); deq.push_back(x); 单调队列是在队列的基础上使它保持

使用LinkedList模拟一个堆栈或者队列数据结构

使用LinkedList模拟一个堆栈或者队列数据结构. 堆栈:先进后出  如同一个杯子. 队列:先进先出  如同一个水管. import java.util.LinkedList; public class DuiLie { private LinkedList link; public DuiLie() { link = new LinkedList(); } public void myAdd(Object obj) { link.addFirst(obj); } public Object

java集合 collection-list-LinkedList 模拟一个堆栈或者队列数据结构。

/* 使用LinkedList模拟一个堆栈或者队列数据结构. 堆栈:先进后出 如同一个杯子. 队列:先进先出 First in First out FIFO 如同一个水管. */ import java.util.*; class DuiLie { private LinkedList link; DuiLie() { link = new LinkedList(); } public void myAdd(Object obj) { link.addFirst(obj); } public O

单调队列(双端队列) poj2823 hdoj3415 hdoj3530

单调队列及其应用(双端队列) 单调队列,望文生义,就是指队列中的元素是单调的.如:{a1,a2,a3,a4--an}满足a1<=a2<=a3--<=an,a序列便是单调递增序列.同理递减队列也是存在的. 单调队列的出现可以简化问题,队首元素便是最大(小)值,这样,选取最大(小)值的复杂度便为o(1),由于队列的性质,每个元素入队一次,出队一次,维护队列的复杂度均摊下来便是o(1). 如何维护单调队列呢,以单调递增序列为例: 1.如果队列的长度一定,先判断队首元素是否在规定范围内,如果超范

Java LinkedList特有方法程序小解 &amp;&amp; 使用LinkedList 模拟一个堆栈或者队列数据结构。

package Collection; import java.util.LinkedList; /* LinkedList:特有的方法 addFirst()/addLast(); getFirst()/getLast(); removeFirst()/removeLast(); 若链表为空,抛出 没有这个元素异常/NoSuchElementException 但是 JDK1.6 版本以后出现了替代方法: offerFirst()/offerLast(); peekFirst()/peekLas