二个栈合成队列

195 阅读3分钟

用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。 队列中的元素为 int 类型。


定义

首先相信大家都清楚队列和栈的特性,栈是先进后出,队列是先进先出。那么知道这个特性后就好办了。

分析:stack1:用来进队列。
 *      stack2:用来出队。先判断stack2中有无元素,若有元素,直接弹出栈顶元素。
 *              若无元素,则从stack1中循环取元素。取完之后,再弹出栈顶的元素。
 
 * 相当于stack1中的元素是正序进入,进入stack2中变成倒序了,这时就实现了队列先进先出的特性

举例:元素123, 用二个栈实现队列。

首先元素进入栈stack1,这时候栈1是321,此时stack2为空,将1中元素全部放入stack2,由于先进后出, 所以这时候出栈为321,因此进入栈2的序列是123(栈顶到栈底),栈2弹出是1,2,3

这样一看不就是123进栈1,123出栈2,相当于个队列


如下图:

  • 入队:

图片.png

  • 出对

图片.png


代码实现:

结构定义myqueue

#include <stdio.h>
#include <stdlib.h>
#define maxsize 100
//创建栈
struct Stack{
int data[maxsize];
int top;
};
typedef struct Stack MyStack;
//队列定义为双栈
typedef struct {
MyStack s1; //S1为主栈
MyStack s2; //S2为用来反转的栈
} MyQueue;

这样就定义了自己的队列是二个栈

初始化

MyQueue* myQueueCreate() {
MyQueue * tempQueue =(MyQueue *)malloc(sizeof(MyQueue)); //申请空间 
tempQueue->s1.top = -1 ; // top最底下是0 -1为空
tempQueue->s2.top = -1 ;
return tempQueue ;
}

入队

void myQueuePush(MyQueue* obj, int x) {
if(obj->s1.top<maxsize)  //如果s1的栈顶<maxsize
{
while(obj->s1.top!=-1) //s1栈不是空栈
{
obj->s2.data[++(obj->s2.top)]=obj->s1.data[(obj->s1.top)--];//把S1栈中元素压入S2实现反转
}
obj->s1.data[++(obj->s1.top)]= x ; //把push新加入入队的元素x压入S1栈(此时S1为空栈,因为它的元素已经全部给S2啦)
while(obj->s2.top!=-1) //s2不是空栈
{
obj->s1.data[++(obj->s1.top)]=obj->s2.data[(obj->s2.top)--];//再把S2栈中的元素全部反转压入S1
}}}

就完成上面那副入队图了

show 展示队列

void show_myQueue(MyQueue * obj)
{
int temp =obj->s1.top ;
while(temp!=-1)  
{
printf("%d ",obj->s1.data[temp--]);
}
printf("\n");
}

展示的是栈1的元素

出队

/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
if(obj->s1.top!=-1) //栈1不空
{
return obj->s1.data[obj->s1.top--] ;  //返回栈顶元素
}
// return NULL ;

}

获取队列 front 元素

/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
if(obj->s1.top!=-1) //栈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) //栈1为空
return true ;
return false ;
}

销毁

void myQueueFree(MyQueue* obj) {
free(obj);
}

main函数

int main()
{
int i ;
MyQueue * myQueue =NULL;
myQueue =myQueueCreate();
for(i=0;i<3;i++)
{
myQueuePush(myQueue,i); //入队123
}
show_myQueue(myQueue);
printf("出队的元素是:%d\n",myQueuePop(myQueue));
printf("此时队列内的首个的元素是:%d\n",myQueuePeek(myQueue));
}

图片.png

总体代码如下:

#include <stdio.h>
#include <stdlib.h>
#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<maxsize)
{
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);
*/

参考

看看其他的,发散一下自己的想法

我刚开始想的也是很多错误