数据结构之栈和队列

栈和队列是基本的线性数据结构,分别遵循后进先出(LIFO)和先进先出(FIFO)原则。栈主要在表尾进行操作,而队列则允许在两端不同位置进行插入和删除。链队列和循环队列是队列的两种实现方式,提高了数据操作的效率。

1. 栈和队列是特殊的线性表,但是不同的抽象数据类型。

2. 栈:是限定近在表尾(即栈顶)进行插入或删除操作(后进先出)的线性表。

#include <iostream>
#include <malloc.h>
using namespace std;

#define SIZE 100
#define INCREMENT 10

#define OK 1
#define ERROR -1
#define OVERFLOW -1
typedef int Status;

template <class T>
struct SqStack
{
private:
    T *base,//栈底指针
    *top; //栈顶指针
public:
    int stacksize;//栈空间大小
    int Length;//当前元素数量

    SqStack()
    {
        base=(T*)malloc(SIZE*sizeof(T));
        if(!base)exit(OVERFLOW);//分配失败
        top=base;
        stacksize=SIZE;
        Length=0;
    }
    T Peek()
    {
        //若栈不空则用e返回但不删除s的栈顶元素
        if(top==base)
        {
            cout<<"当前栈为空"<<endl;
        }
        return *(top-1);
    }
    Status Push(T e)
    {
        //插入新元素在栈顶
        if(top-base>=stacksize)
        {
            base=(T*)realloc(base,(stacksize+INCREMENT)*sizeof(T));
            if(!base)exit(OVERFLOW);
            top=base+stacksize;
            stacksize+=INCREMENT;
        }
        *top++=e;
        Length++;
        return OK;
    }
    T Pop()
    {
        //若栈不空则用e返回且删除s的栈顶元素
        if(top==base)
        {
            cout<<"当前栈为空"<<endl;
            return ERROR;
        }
        T temp = *--top;
        Length--;
        return temp;
    }
};

int main()
{
    SqStack<int> s;
    s.Push(10);
    s.Push(20);
    cout<<s.Pop()<<endl;
    cout<<s.Pop()<<endl;
    cout<<s.Pop()<<endl;
}

3. 队列:先进先出的线性表,只允许在表一端(队尾)插入,在另一端(队头)删除元素

链队列

#include <iostream>
#include <malloc.h>
using namespace std;

#define OK 1
#define ERROR -1
#define OVERFLOW -1
typedef int Status;

template <class T>
struct Node{
    T data;
    Node*next;

    Node()
    {
        next=NULL;
    }
};
template <class T>
struct LinkQueue
{
private:
    Node<T> *head,//队头指针
            *rear;//队尾指针
public:
    int Length;

    LinkQueue(){
        head=rear=new Node<T>();
        Length=0;
    }
    Status EnQueue(T e)
    {
        Node<T> *s=new Node<T>();
        s->data=e;
        rear->next=s;
        rear=s;
        Length++;
        return OK;
    }
    T DeQueue()
    {
        if(rear==head)
        {
            cout<<"当前队列为空"<<endl;
            return ERROR;
        }
        Node<T> *p=head->next;
        T e=p->data;
        head->next=p->next;
        if(rear==p)rear=head;
        delete p;
        Length--;
        return e;
    }
    T Peek()
    {
        if(rear==head)
        {
            cout<<"当前队列为空"<<endl;
            return ERROR;
        }
        return head->next->data;
    }
};

int main()
{
    LinkQueue<int> lq;
    lq.EnQueue(10);
    lq.EnQueue(20);
    cout<<lq.Peek()<<endl;
    cout<<lq.DeQueue()<<endl;
    cout<<lq.DeQueue()<<endl;
    cout<<lq.DeQueue()<<endl;
}

循环队列

#include <iostream>
#include <malloc.h>
using namespace std;

#define OK 1
#define ERROR -1
#define OVERFLOW -1
typedef int Status;

//循环队列
#define MAXSIZE 100 //队列最大长度
template <class T>
struct SqQueue
{
private:
    T *base;
    int head; //队头指针
    int rear; //队尾指针
public:
    int Length;

    SqQueue()
    {
        base=(T*)malloc(MAXSIZE*sizeof(T));
        if(!base)exit(OVERFLOW);
        head=rear=0;
    }
    Status EnQueue(T e)
    {
        //拿出一个元素空间,约定“队头指针与队尾指针相邻且在下一位时队列就满”,
        //此时当队头指针和队尾指针相等的时候就会是队列为空的时候
        if((rear+1)%MAXSIZE==head)
        {
            cout<<"队列已满"<<endl;
            return ERROR;
        }
        base[rear]=e;
        rear=(rear+1)%MAXSIZE;
        Length++;
        return OK;
    }
    Status DeQueue()
    {
        //若队列不空,返回队头元素并移除
        if(rear==head)
        {
            cout<<"当前队列为空"<<endl;
            return ERROR;
        }
        T e=base[head];
        head=(head+1)%MAXSIZE;
        Length--;
        return e
    }
};

int main()
{
    SqQueue<int> sq;
    sq.EnQueue(10);
    sq.EnQueue(20);
    cout<<sq.DeQueue()<<endl;
    cout<<sq.DeQueue()<<endl;
    cout<<sq.DeQueue()<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值