栈和队列

栈和队列

  • 定义:栈是一种只能在一端进行插入或删除操作的线性表。

1.允许进行插入、删除操作的一端称为栈顶
2.表的另一端称为栈底
3.当栈中没有数据元素时,称为空栈 4.栈的插入操作通常称为进栈
5.栈的删除操作通常称为退栈

  • 栈的主要特点:元素后进先出
  • 栈的几种基本运算:

InitStack(&s):初始化栈。构造一个空栈s
DestroyStack(&s):销毁栈。释放s占用的存储空间。
StackEmpty(s):判断栈是否为空;若栈s为空,则返货真;否则返回假
Push(&S,e):进栈。将元素e插入到栈顶
Pop(&s,&e):出栈。从栈s中退出栈顶元素,并将其赋值给e
GetTop(s,&e):取栈顶元素。返回当前的栈顶元素,并将其值赋给e

顺序栈:

//定义
typedef struct{
    ElemType data[MaxSize];
    int top;    //栈顶指针
}SqStack;

//初始化
void InitStack(){
    s = (SqStack*)malloc(sizeof(SqStack));
    s->top = -1;
}

//销毁栈
void DestroyStack(SqStack* &s){
    free(s);
}

//判断栈是否为空栈
bool StackEmpty(SqStack* s){
    return (s->top == -1);
}

//进栈
bool Push(SqStack* &s,ElemType e){
    if(s->top == MaxSize-1)
        return false;
    s->top++;
    s->data[s->top] = e;
    return true;
}

//出栈
bool Pop(SqStack* &s,ElemType& e){
    if(s->top == -1)
        return false;
    e = s->data[s->top];
    s->top--;
    return true;
}

//取栈顶元素
bool GetTop(SqStack* s,ElemType& e){
    if(s->top == -1)
        return false;
    e = s->data[s->top];
    return true;
}

链栈:

链栈的4要素

  1. 栈空条件:s->next=NULL
  2. 栈满条件:不考虑
  3. 进栈操作:将包含e的节点插入到头节点之后
  4. 退栈操作:取出头节点之后节点的元素并删除之
typedef struct linknode{
    ElemType data;
    struct linknode* next;
}LiStack;

//初始化栈
void initStack(LiStack* &s){
    s = (LiStack*)malloc(sizeof(LiStack));
    s->next = NULL;
}

//销毁栈
void DestroyStack(LiStack* &s){
    LiStack* p = s, *q = s->next;
    while(q != NULL){
        free(p);
        p = q;
        q = p->next;
    }
    free(p);
}

//进栈
void Push(LiStack* &s,ElemType e){
    LiStack* p = NULL;
    p = (LiStack*)malloc(sizeof(LiStack));
    p->data = e;
    p->next = s->next;
    s->next = p;
}

//出栈
void Pop(LiStack* &s,ElemType e){
    LiStack* p = NULL;
    if(s->next == NULL)
        return false;
    p = s->next;
    e = p->data;
    s->next = p->next;
    free(p);
}

//取栈顶元素
bool GetTop(LiStack* s,ElemType& e){
    if(s->next == NULL)
        return false;
    e = s->next->data;
    return true;
}
  • 栈的应用

当判断一组数据是不是对称时可以使用栈来判断,让数据依次进栈,产生的出栈序列与原数据序列相同

bool symmetry(ElemType str[]){
    int i; ElemType e; SqStack* st;//初始化栈
    for(i=0;str[i]!='\0';i++)//将串所有元素进栈
        Push(st,str[i]);//元素进栈
    for(i=0;str[i]!='\0';i++){
        Pop(st,e);
        if(str[i]!=e){
            DestroyStack(st);
            return false;
        }
    }
    DestroyStack(st);
    return true;
}

队列

  • 定义:队列简称队,它是一种运算受限的线性表。

队列只能选取一个端点进行插入操作,另一个端点进行删除操作
执行插入操作的称为队尾(rear)
执行删除的一端称为队头(front)
向队列中插入一个元素称为进队,新元素进队成为新的队尾
从队列中删除元素称为出队,元素出队后,后继元素成为新的队首

  • 队列的基本操作

1.初始化队列,构造一个空队列
2.销毁队列。释放队列q占用的存储空间
3.判断队列是否为空。若队列为空,则返回真;否则返回假
4.进队列。将元素e进队作为队尾元素
5.出队列。从队列中出队一个元素,并将其赋值给e

  • 顺序队
/*
1.队空条件:front=rear
2.队满条件:(rear+1)%MaxSize=front
3.元素e进队:rear=(rear+1)%MaxSize
4.元素e出队:front=(front+1)%MaxSize
5.元素个数:count=(rear-front+MaxSize)%MaxSize
*/
//定义
typedef struct{
    ElemType data[MaxSize];
    int front;
    int rear;
}SqQueue;

//初始化
void initQueue(SqQueue* &q){
    q = (SqQueue*)malloc(sizeof(SqQueue));
    q->front = -1;
    q->rear = -1;
}

//销毁
void DestroyQueue(SqQueue*&q){
    free(q);
}

//判空
void isEmpty(SqQueue*&q){
    if(q->front == q->rear)
        return false;
    return true;
}

//进队
bool enQueue(SqQueue*&q,ElemType &e){
    if(q->rear == MaxSize-1)
        return false;
    q->rear = (q->rear+1) % MaxSize;
    q->data[q->rear] = e;
    return true;
}

//出队
bool deQueue(SqQueue*&q,ElemType&e){
    if(q->front == q->rear)
        return false;
    e = q->data[front];
    q->front = (front+1)%MaxSize;
    return true;
}

链式队列:

/*
1.队空条件:front=rear=NULL
2.对满条件:不考虑
3.进队操作:将包含e的节点插入到链表尾部
4.出队操作:删除单链表首数据节点
*/

//定义
typedef struct qnode{
    ElemType data;
    struct qnode* next;
}QNode;

typedef struct{
    QNode* front;
    QNode* rear;
}LiQueue;

//初始化队列
void InitQueue(LiQueue*&q)
{
    q=(LiQueue*)malloc(sizeof(LiQueue));
    memset(q,0,sizeof(LiQueue));
}

//销毁队列
void DestrpyQueue(LiQueue*&q)
{
    QNode* p = q->front, *r;
    if(p != NULL){
        r = p->next;
        while(r != NULL){
            free(p);
            p = r;
            r = p->next;
        }
    }
    free(p);
    free(q);
}

//判断队列是否为空
bool isEmpty(LiQueue* q)
{
    return (q->rear==NULL);
}

//进队
void enQueue(LiQueue*&q,ElemType e)
{
    QNode* p;
    p = (QNode*)malloc(sizeof(QNode));
    p->data = e;
    p->next = NULL;
    if(q->rear == NULL){//若链队为空,新节点是队首节点又是队尾节点
        q->front = p;
        q->rear = p;
    }else{
        q->rear->next = p;//将*p节点链到队尾,并将rear指向它
        q->rear = p;
    }
}

//出队
bool deQueue(LiQueue*&q,ElemType& e)
{
    QNode* t;
    if(q->rear == NULL) return false;//队列为空
    t = q->front;                    //t指向第一个数据节点
    if(q->front == q->rear){         //队列中只有一个节点时
        q->front = NULL;
        q->rear = NULL;
    }else{
        q->front = q->front->next;
    }
    e = t->data;
    free(t);
    return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值