• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

数据结构-用栈实现队列

武飞扬头像
养乌龟的小少年
帮助1

前言:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

学新通


目录

1.栈得实现

1.1结构体定义

1.2初始化栈

1.3压栈函数

1.4出栈函数

1.5返回栈顶函数

1.6判空函数 

 1.7销毁函数

 2.题目解析

3.软件程序 

 3.1结构体定义及初始化

3.2进队函数 

 3.3出队函数

 3.3返回队头元素

3.4判空函数 

 3.5销毁函数


1.栈得实现

这个题我是使用C语言解法进行解题得,因为要使用栈实现队列,所以首先我们要有栈得源函数,我在这里就把之前写过得栈得源函数按功能分类拷贝下来:代码如下:

1.1结构体定义

  1.  
    typedef int STDataType;
  2.  
    typedef struct Stack
  3.  
    {
  4.  
    STDataType* a;//数组栈
  5.  
    int top;//栈顶
  6.  
    int capacity;//容量
  7.  
    }ST;

1.2初始化栈

  1.  
    void StackInit(ST* ps)
  2.  
    {
  3.  
    assert(ps);
  4.  
    ps->a = NULL;
  5.  
    ps->top = 0; // ps->top = -1;
  6.  
    ps->capacity = 0;
  7.  
    }

1.3压栈函数

  1.  
    void StackPush(ST* ps, STDataType x)
  2.  
    {
  3.  
    assert(ps);
  4.  
     
  5.  
    if (ps->top == ps->capacity)
  6.  
    {
  7.  
    int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
  8.  
    STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newCapacity);
  9.  
     
  10.  
     
  11.  
    if (tmp == NULL)
  12.  
    {
  13.  
    printf("realloc fail\n");
  14.  
    exit(-1);
  15.  
    }
  16.  
     
  17.  
    ps->a = tmp;
  18.  
    ps->capacity = newCapacity;
  19.  
    }
  20.  
     
  21.  
    ps->a[ps->top] = x;
  22.  
    ps->top ;
  23.  
    }
学新通

1.4出栈函数

  1.  
    void StackPop(ST* ps)
  2.  
    {
  3.  
    assert(ps);
  4.  
    assert(!StackEmpty(ps));
  5.  
     
  6.  
    ps->top--;
  7.  
    }

1.5返回栈顶函数

  1.  
    STDataType StackTop(ST* ps)
  2.  
    {
  3.  
    assert(ps);
  4.  
    assert(!StackEmpty(ps));
  5.  
     
  6.  
    return ps->a[ps->top - 1];
  7.  
    }

1.6判空函数 

  1.  
    bool StackEmpty(ST* ps)
  2.  
    {
  3.  
    assert(ps);
  4.  
     
  5.  
    /*if (ps->top == 0)
  6.  
    {
  7.  
    return true;
  8.  
    }
  9.  
    else
  10.  
    {
  11.  
    return false;
  12.  
    }*/
  13.  
    return ps->top == 0;
  14.  
    }

 1.7销毁函数

  1.  
    bool StackEmpty(ST* ps)
  2.  
    {
  3.  
    assert(ps);
  4.  
     
  5.  
    /*if (ps->top == 0)
  6.  
    {
  7.  
    return true;
  8.  
    }
  9.  
    else
  10.  
    {
  11.  
    return false;
  12.  
    }*/
  13.  
    return ps->top == 0;
  14.  
    }

 2.题目解析

 我们知道队列是先进先出得,数据得进出如下图所示:

学新通 

而栈得数据是先进后出, 如果上面数据进入栈内,先出的肯定就是数据6,不符合队列要求的数字1先出,所以我们要使用两个栈,一个栈pushST用来将所有数据存储进去,另一个栈popST用来出数据,这样就会把栈底得数据,在出数据得得栈中第一个出去,就满足队列得先进先出得原则。图解图下:

学新通

我们如果这时候想入数据,应该往pushST这个栈里面入,出数据就看popST栈中有无数据,没有数据就往里添pushST中得数据,如果有直接出,如下图所示:

学新通

学新通 

3.软件程序 

 3.1结构体定义及初始化

  1.  
    typedef struct {
  2.  
    ST pushST; //定义一个专门存数据得栈
  3.  
    ST popST;//定义一个专门出数据得栈
  4.  
     
  5.  
    } MyQueue;
  6.  
     
  7.  
     
  8.  
    MyQueue* myQueueCreate() {
  9.  
    MyQueue *q = (MyQueue*)malloc(sizeof(MyQueue)); //定义一个结构体指针变量 指向两个栈
  10.  
    StackInit(&q->pushST);//初始化
  11.  
    StackInit(&q->popST);
  12.  
     
  13.  
    return q;
  14.  
     
  15.  
    }
学新通

3.2进队函数 

  1.  
    void myQueuePush(MyQueue* obj, int x) {
  2.  
    StackPush(&obj->pushST,x); // 开始存数据
  3.  
     
  4.  
    }

 3.3出队函数

要先判断栈里面是否为空,为空要先进数据。题目要求 要返回出队得元素,所以我们要定义个变量用来存储出队得数据,代码如下:

  1.  
    int myQueuePop(MyQueue* obj) {
  2.  
    //如果出栈得数据为空得话,要将存数据得栈内数据放进出栈
  3.  
    if(StackEmpty(&obj->popST))
  4.  
    {
  5.  
    while(!StackEmpty(&obj->pushST))
  6.  
    {
  7.  
    StackPush(&obj->popST,StackTop(&obj->pushST));
  8.  
    StackPop(&obj->pushST);
  9.  
    }
  10.  
    }
  11.  
    int front = StackTop(&obj->popST);
  12.  
    StackPop(&obj->popST);
  13.  
    return front;
  14.  
    }

 3.3返回队头元素

返回的队头元素即为,出栈得栈定元素,代码如下:

  1.  
    int myQueuePeek(MyQueue* obj) {
  2.  
    if(StackEmpty(&obj->popST))
  3.  
    {
  4.  
    while(!StackEmpty(&obj->pushST))
  5.  
    {
  6.  
    StackPush(&obj->popST,StackTop(&obj->pushST));
  7.  
    StackPop(&obj->pushST);
  8.  
    }
  9.  
    }
  10.  
    //返回栈定数据
  11.  
    return StackTop(&obj->popST);
  12.  
    }

3.4判空函数 

如果pushST栈 以及popST栈都为空得话 则队列为空,直接用表达式真假判断即可,代码如下:

  1.  
    bool myQueueEmpty(MyQueue* obj) {
  2.  
     
  3.  
    return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);
  4.  
     
  5.  
    }

 3.5销毁函数

 我们需要先销毁两个栈,再销毁 自定义结构体指针变量得指向,图解如下:

学新通

代码如下: 

  1.  
    void myQueueFree(MyQueue* obj) {
  2.  
    StackDestroy(&obj->pushST);
  3.  
    StackDestroy(&obj->popST);
  4.  
    free(obj);
  5.  
     
  6.  
    }

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhieefhj
系列文章
更多 icon
同类精品
更多 icon
继续加载