【数据结构】——队列和栈、堆和栈

1、队列和栈

在数据结构中,队列和栈是我们再熟悉不过的两种结构了叭,简单来说,栈就是“先进后出”的结构,队列就是“先进先出”的结构。下面我们来具体实现它吧~

1.1队列的实现

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<conio.h>
using namespace std;

typedef struct student
{
    int data;
    struct student* next;
}node;

typedef struct QueueLink
{
    node* front;
    node* rear;
}queue;

//队列的入队
queue *insert(queue *HQ, int x)
{
    node* s;
    s = (node*)malloc(sizeof(node));
    s->data = x;
    s->next = NULL;

    if(HQ->rear == NULL)
    {
        HQ->front = s;
        HQ->rear = s;
    }
    else
    {
        HQ->rear->next = s;
        HQ->rear = s;
    }
    return HQ;
}

//队列的出队
queue *del(queue *HQ)
{
    node* p;
    int x;
    if(HQ->first == NULL)
    {
        printf("yichu");
    }
    else
    {
        x = HQ->first->data;
        p = HQ->first;
        if(HQ->front == HQ->rear)
        {
            HQ->front = NULL;
            HQ->rear = NULL;
        }
        else
        {
            HQ->front = HQ->front->next;
            free(p);
        }
        return HQ;
    }
}

1.2栈的实现

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<conio.h>
using namespace std;

typedef struct student
{
    int data;
    struct student* next;
}node;

typedef struct StackLink
{
    node* zhandi;
    node* top;
}stack;

//入栈
stack* push(stack *HQ,int x)
{
    node* s;
    s = (node*)malloc(sizeof(node));
    s->data = x;
    s->next = NULL;

    if(HQ->zhandi == NULL)
    {
        HQ->zhandi = s;
        HQ->top = s;

    }
    else
    {
        HQ->top->next = s;
        HQ->top = s;
    }
    return HQ;
}

//出栈
queue *pop(queue *HQ)
{
    node* p;
    int x;
    if(HQ->zhandi == NULL)
    {
        printf("yichu\n");
    }
    else
    {
        p = HQ->zhandi;
        x = HQ->zhandi->data;
        if(HQ->zhandi == HQ->top)
        {
            HQ->zhandi = NULL;
            HQ->top = NULL;
        }
        else
        {
            while(p->next != HQ->top)
            {
                p = p->next;
            }
            HQ->top = p;
            HQ->top->next = NULL;
        }
        return HQ;
    }
}

1.3用一个队列来实现栈结构

实质上就是使用先进先出的原则实现先进后出的结构,所以,C++实现,用一个队列即可实现,只用将n-1队尾元素拿出来头插,再出队尾元素,或是删除队尾元素,即可实现一个栈先进后出的功能

代码实现:

class MyStack {
public:
    /** Initialize your data structure here. */
    MyStack() {

    }
    /** Push element x onto stack. */
    void push(int x) {
        q1.push(x);
    }
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
        int size = q1.size() - 1;
        for(size_t i = 0; i < size ;++i)
        {
            q1.push(q1.front());
            //把队列前面的元素全部拿出来重新入队
            q1.pop();
        }
        //此时栈顶元素就是队列的队头元素
        int front = q1.front();
        //出队
        q1.pop();
        return front;
    }
    /** Get the top element. */
    int top() {
        return q1.back();
    }
    /** Returns whether the stack is empty. */
    bool empty() {
        if(q1.empty())
            return true;
        else
            return false;
    }
    private:
    queue<int> q1;
};

1.4用一个栈实现队列结构

实质上是使用先进后出的性质实现先进先出的结构。 所以,用c++实现,一个栈就可以。只用将栈顶n-1个元素拿出来入队,然后返回栈底的值,再把队列里面的元素出队入栈。重复上述操作即可。

代码实现:



class MyQueue {
public:
    stack<int> s;
    stack<int> h;
    /** Initialize your data structure here. */
    MyQueue() {
    }
    /** Push element x to the back of queue. */
    void push(int x) {
        s.push(x);
    }
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        while(s.size() != 1)
        {
            h.push(s.top());
            s.pop();
        }
        int ans = s.top();
        s.pop();
        while(!h.empty())
        {
            s.push(h.top());
            h.pop();
        }
        return ans;
    }

    /** Get the front element. */
    int peek() {
        while(s.size() != 1)
        {
            h.push(s.top());
            s.pop();
        }
        int ans = s.top();
        while(!h.empty())
        {
            s.push(h.top());
            h.pop();
        }
        return ans;

    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return s.empty();
    }
};

1.5用两个栈实现队列的功能

#include<stack>
#include<iostream>
uisng namespace tsd;
tempalte<class T>

struct MyQueue
{
    void push(T &t)
    {
        s1.push(t);
    }

    T front()
    {
        if(s2.empty())
        {
            if(s1.size() == 0) throw;
            while(!s2.empty())
            {
                s2.push(s1.top());
                s1.pop();
            }
        }
        return s2.top();
    }

    void pop()
    {
        if(s2.empty())
        {
            while(!s1.empty())
            {
                s2.push(s1.top());
                s1.pop();
            }
            
        }
        if(! s2.empty())
            s2.pop();
    }
    stack<int> s1;
    stack<int> s2;
};

2、堆和栈的区别

首先我们来了解一下内存一般分为哪几个类别

  1. 栈区:由编译器自动分配和释放。存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈
  2. 堆区:一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。注意,这个数据结构中的堆不是一回事儿,这更类似于链表
  3. 全局区(静态区):全局变量和静态变量存放在一起的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态比阿娘在相邻的另一块区域。程序结束后由系统释放
  4. 文字常量区:常量字符串就放在这里,程序结束后由系统释放
  5. 程序代码区区:存放函数体的二进制代码
    具体的解释请参考另外一篇博文进程的虚拟地址空间

接下来,我们就来详细的介绍他们之间的区别吧~
1、申请方式
栈是由系统自动分配,但是堆是程序员自己申请的。例如:p1=(char*)mallco(10);和int *p2 = new int(10).注意!!!p1和p2本身是在栈中的。
2、申请后系统的响应
只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则报错。而对于堆来说,我们知道操作系统有一个记录空闲内存地址的链表,堆的调用就去链表中寻找符合自己申请空间的节点,这块内存空间中的首地址记录本次分配的大小。
3、申请大小的限制
在windows下,栈的大小是2MB。而堆获取的空间比较灵活,也比较大
4、申请效率的比较
因为栈是程序自动分配,所以速度比较快但是程序员无法控制。但是new一般速度比较慢,而且容易产生碎片,但是用起来很方便。
5、栈和堆的存储内容
栈:在函数调用的时候。第一个进栈的是主函数中的下一条指令的地址,然后是函数的各个参数,然后是参数从右向左入栈,然后是局部变量。注意!!!静态变量是不入栈的。
堆:一般是在堆的头部用一个字节存放堆的大小,堆中的内容由程序员自行安排
6、存取效率的比较
栈中的数据是在运行的时候赋值的,但是堆中的数据是在编译时就确定的。栈比堆快。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值