两个栈实现一个队列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两个栈实现一个队列相关的知识,希望对你有一定的参考价值。

  今天终于有时间来写这个了,我为了简单,就没有用自定义结构来实现栈,直接用了两个数组来实现栈结构。

  这个算法,根据理解个人认为两个栈实现队列最主要考察的应该是用链栈来实现,感觉如果是链栈来实现对于节点的处理会稍微麻烦一些吧。不然的话并不难,就是数组下标的处理罢了。但尽管是数组也还是挺麻烦的,对于下标处理真是需要考虑得仔细些,不然有点头晕。

  不管用什么来实现吧,先说说这个算法的思路,我能想到的让时间复杂度优化的方法就2个吧,第2种比较好:

  1.栈1负责入队,然后,出队的时候,把栈1除栈底的外倒入栈2,然后令栈1底为空,然后,要入队的时候再把栈2的倒回栈1,这样节省的时间就是如果时连续出队的话,只用继续把栈2的顶弹出即可,但如果是一只交替的进出就不怎么好了。于是,我的办法就是另外一种。

  2.大概就是栈1只负责入队,栈2只负责出队即可,基本上不用倒入,需要倒入的情况只有第一次出队和当栈2为空时(栈2为空即无法出队),入队时就直接入栈1,出队时判断栈2是否为空,如果不为空则出队,否则为空,就把栈1的全部倒入栈2,这样对于频繁的进出操作会节省时间一些。

  总之实现都不难,下面是我的代码(改天有空再把它改成函数调用的):

/**
 *      两个栈实现一个队列
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#define N 10

int main(void)
{
    int stack1[N], stack2[N];
    int i, j, k; ///i记录栈1,j记录栈2
    char c;

    i = j = 0;
    puts("1) 进队    2) 出队");
    puts("3) 队首    4) 队尾");
    puts("5) 队列    6) 队员个数");
    puts("7) 退出");
    while((c = getch()) != 7)
    {
        switch(c)
        {
        case 1 :  printf("\n进队:");
                    if(i < N)
                        scanf("%d", &stack1[i++]);
                    else
                        printf("Queue overflow!\n");
                break;
        case 2 :  printf("\n出队\n");
                    if(j == 0 && i != 0)      ///栈2为空时,将栈1除底外的倒入栈2
                    {
                        for(j = 0; j < i - 1; j++)
                        {
                            stack2[j] = stack1[i - 1 - j];
                        }
                        i = 0;
                    }
                    else if(j > 0)  ///栈2不为空,则出队只用花O(1)的时间
                    {
                        j--;
                    }
                    else
                    {
                        printf("Queue overflow!\n");
                    }
                break;
        case 3 :  if(i != 0 && i + j != 0)
                        printf("\n队首元素:%d\n", stack1[0]);
                    else if(i == 0 && i + j != 0)
                        printf("\n队首元素:%d\n", stack2[j - 1]);
                    else
                        printf("Queue is Empty!\n");
                break;
        case 4 :  if(j != 0 && i + j != 0)
                        printf("\n队尾元素:%d\n", stack2[0]);
                    else if(j == 0 && i + j != 0)
                        printf("\n队尾元素:%d\n", stack1[i - 1]);
                    else
                        printf("Queue is Empty!\n");
                break;
        case 5 :  printf("\n显示数据:\n");
                    if(i + j != 0)
                    {
                        if(j == 0)          ///如果栈2为空,则只需显示栈1的
                        {
                            for(k = 0; k < i; k++)
                                printf("%d ", stack1[k]);
                        }
                        else                ///否则栈2不为空
                        {
                            for(k = j - 1; k >= 0; k--)
                                printf("%d ", stack2[k]);
                            if(i > 0)
                            {
                                for(k = 0;k < i; k++)
                                    printf("%d ", stack1[k]);
                            }
                        }
                    }
                    else
                        printf("Queue is Empty!\n");
                break;
        case 6 :  printf("\n当前队员个数为: %d\n", i + j);
                break;
        }
    }

    return 0;
}

  改天再试试两个队列实现一个栈...emmm,我也还没思考过怎么实现。

  最后,小小的感谢一下自己的思考吧~

以上是关于两个栈实现一个队列的主要内容,如果未能解决你的问题,请参考以下文章

两个栈实现一个队列

用两个栈实现队列-剑指Offer

用两个栈实现一个队列

用两个栈实现一个队列(C++)

剑指offer-用两个栈实现队列

剑指offer用两个栈实现队列