用两个栈模拟无限长队列

思路:设置两个栈,栈1起入队的作用、栈2起出队的作用.入队时,所有元素进栈1,栈满时会通过realloc函数追加存储空间
并且保存原来栈1的元素.出队时,先判断栈2是否为空,若为空,则会判断栈1是否为空,栈1为空,则说明队列为空,栈1不为空
则将栈1的元素全部出栈并入栈2,栈2满时依然通过realloc追加存储空间,然后栈2元素出栈;若栈2不为空,栈2元素直接出栈

extern void *realloc(void *mem_address, unsigned int newsize);
功能:先释放原来mem_address所指内存区域,并按照newsize指定的大小重新分配空间,
同时将原有数据从头到尾拷贝到新分配的内存区域,并返回该内存区域的首地址,即重新分配存储

#include <stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 3//定义栈初始空间的容量
#define STACKINCREMENT 3//存储空间的分配增量
typedef char elementtype;
//栈1作入栈用,栈2作出栈用
typedef struct sqstack{
    elementtype *top;//栈顶指针
    elementtype *base;//栈底指针
    int stacksize;//当前已分配的空间,以栈元素的个数为单位
}sqstack;
sqstack *s1 = (sqstack*)malloc(sizeof(sqstack));
sqstack *s2 = (sqstack*)malloc(sizeof(sqstack));
int inistack()
{
    s1->base = (elementtype*)malloc(sizeof(elementtype)*STACK_INIT_SIZE);//access violation
    s2->base = (elementtype*)malloc(sizeof(elementtype)*STACK_INIT_SIZE);
    if(!s1->base && !s2->base)
        return 0;
     s1->top = s1->base;//栈空时,栈顶指针和栈底指针位置相同
    s2->top = s2->base;
    s1->stacksize = s2->stacksize = STACK_INIT_SIZE;
    return 1;
}
int enstack(char t,int c)
{
    if(c == 1)
    {
        if(s1->top - s1->base == s1->stacksize)//栈1满
        {
            s1->base = (elementtype*)realloc(s1->base,sizeof(elementtype)*(s1->stacksize+STACKINCREMENT));//追加存储空间
            if(!s1->base)//空间开辟失败
                return 0;
            s1->stacksize += STACKINCREMENT;//修改栈容量
        }
        *(s1->top)++ = t;
        return 1;
    }
    else{
        if(s2->top - s2->base == s2->stacksize)//栈2满
        {
            s2->base = (elementtype*)realloc(s2->base,sizeof(elementtype)*(s2->stacksize+STACKINCREMENT));//追加存储空间
            if(!s2->base)//空间开辟失败
                return 0;
            s2->top = s2->base + s2->stacksize;//修改栈顶指针的新值
            s2->stacksize += STACKINCREMENT;//修改栈容量
        }
        *(s2->top)++ = t;
        return 1;
    }
}
int popstack(char &t)
{
    if(s2->top == s2->base)//栈2空
    {
        if(s1->top == s1->base)//如果栈1也空,则队列为空
            return 0;
        else{//栈1的所有元素出栈,入栈2
            while(s1->top != s1->base)
            {
                enstack(*(--s1->top),2);//入栈2
            }
        }
    }
    t = *(--s2->top);
    return 1;
}
void QueueMenu()
{
    printf("\t\t\t~~~两个栈模拟无限长队列~~~\n");
    printf("\t\t\t\t1.元素入队\n");
    printf("\t\t\t\t2.元素出队\n");
    printf("\t\t\t\t3.显示队列\n");
    printf("\t\t\t\t4.清空队列\n");
}
int enqueue(char t)
{
    return enstack(t,1);
}
int dequeue(char &t)
{
    return popstack(t);
}
int showqueue()
{
    if(s2->top == s2->base && s1->top == s1->base)
        return 0;
    else{
        printf("队列元素为:");
        elementtype *s = s2->top;
        while(s != s2->base)
            printf("%c ",*(--s));
        //此处依然是栈的操作
        s = s1->base;
        while(s1->top != s)
            printf("%c ",*s++);
        printf("\n");
        return 1;
    }
}
int delqueue()
{
    free(s1->base);
    free(s2->base);
    return inistack();
}
int main()
{
    int a;
    inistack();
    while(1)
    {
        QueueMenu();
        printf("请输入你的选择:");
        scanf("%d",&a);
        while(a < 1 || a > 4)
        {
            fflush(stdin);//清除缓存
            system("pause");
            system("cls");
            QueueMenu();
            printf("请重新输入你的选择:");
            scanf("%d",&a);
        }
        //inistack();
        char t;
        switch(a)
        {
        case 1:
            fflush(stdin);//
            printf("请输入要入队的元素:");
            scanf("%c",&t);
            if(enqueue(t))
                printf("元素入队成功!\n");
            else
                printf("队满,元素入队失败!\n");
            break;
        case 2:
            if(dequeue(t))
                printf("出队元素为:%c\n",t);
            else
                printf("队空!出队失败!\n");
            break;
        case 3:
            if(!showqueue())
                printf("队列为空!\n");
            break;
        default:
            if(delqueue())
                printf("队列清空\n");
            else
                printf("重新创建失败,队列未被清空\n");
        }
        fflush(stdin);
        system("pause");
        system("cls");
    }
    return 0;
}
时间: 2024-10-05 02:32:28

用两个栈模拟无限长队列的相关文章

用两个栈模拟实现一个队列

题目:如何用两个栈模拟实现一个队列?  如果这两个堆栈的容量分别是m和n(m>n),你的方法能保证的队列容量是多少?(这里讨论的是顺序栈,如果是链式栈的话完全没有必要考虑空间) 分析:栈的特点是“后进先出(LIFO)”,而队列的特点是“先进先出(FIFO)”.用两个栈模拟实现一个队列的基本思路是:用一个栈作为存储空间,另一个栈作为输出缓冲区,把元素按顺序压入两栈(模拟的队列),并按此顺序出队并输出即可. 如下图,用容量为m的栈作为存储空间,容量为n的栈作为输出缓冲区,一开始先将n个元素压入(pu

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

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

web前端面试系列 - 数据结构(两个栈模拟一个队列)

一. 用两个栈模拟一个队列 思路一: 1. 一个栈s1作为数据存储,另一个栈s2,作为临时数据存储. 2. 入队时将数据压人s1 3. 出队时将s1弹出,并压人s2,然后弹出s2中的顶部数据,最后再将剩余数据弹出s2,并压人s1. 思路二: 1. 一个栈s1作为数据存储,另一个栈s2,作为临时数据存储. 2. 入队时,判断s1, 是否为空,如果不为空,则将数据直接压入s1, 如果为空,则将s2中的数据全部倒入s1,在将数据压人s1. 3. 出队时,判断s2, 是否为空,如果不为空,则直接弹出s2

【干货】容器适配器实现两个栈模拟队列

用两个栈模拟队列的思想就是"倒水思想",这里我们用自定义类型模拟出线性表,再用线性表做容器实现栈的数据结构,最后用栈来实现队列,代码如下: #include<iostream> #include<string> #include<cassert> struct __TrueType//类型萃取 { bool Get() { return true; } }; struct __FalseType { bool Get() { return false

两个栈模拟一个队列和两个队列模拟一个栈

此为网易的一道笔试题.到时候秀逗,不知所云.后来研究之后记录下,以备以后经常翻阅. 栈:先进后出 push和pop 队列:先进先出 offer和poll (1)两个栈模拟一个队列 即将先进后出实现先进先出.比较容易理解,只要所有数据先往一个栈里push,然后将该栈中的数据依次pop出来再push进第二个队列,则顺序自然颠倒过来了,则每次pop是从第二个队列中取数据. import java.util.*; public class StackQueue{ private Stack<Intege

7 两个栈模拟队列,两个队列模拟栈

利用两个栈模拟队列 stack1,stack2 首先向stack1当中放入数据,如果需要输出数据,从stack2中delete数据,如果stack2为空,就把stack1中数据导入stack2 <span style="font-size:14px;">#include "static.h" #include <iostream> #include <stack> template<typename T> class

利用两个栈模拟队列

/************************************************** 题目:用两个栈模拟队列的基本操作1入队2,出队3判断队空4判断队满 s1做为输入栈的元素,一个个压栈相当于入队 s2作为输出队列的元素, 一个个出栈相当于出队 *************************************************/ #include <iostream> #include <cstdio> using namespace std; c

两个栈模拟一个队列

两个栈模拟一个队列,1号栈为入队,栈顶表示队尾:2号栈为出队,栈顶表示队首. 入队,直接进1号栈:出队,先判断2号栈是否有元素,有元素就直接弹出栈顶即队首,如果2号栈没有元素,则将1号栈的元素顺序弹出并进2号栈. [cpp] view plaincopy #include <iostream> #include <stack> #include <assert.h> using namespace std; template<typename T> clas

使用两个栈模拟一个队列

接着上一篇"使用两个队列模拟一个栈",这里该如何使用两个栈模拟一个队列呢?具体实现如下: 1 public class Queue<E>{ 2 private Stack<E> s1 = null; //s1作为插入栈 3 private Stack<E> s2 = null; //s2作为弹出栈 4 5 public Queue(){ 6 s1 = new Stack<E>(); 7 s2 = new Stack<E>();