3.栈与队列

栈与队列概述

1.栈

  • 定义:只能在表的一端(栈顶)进行插入和删除运算的线性表。其中,表尾端称为栈顶 (top), 表头端称为栈底 (base)。 不含元素的栈称为空栈;
  • 栈和队列是限定插入和删除只能在表的“端点”进行的线性表;

在这里插入图片描述

2.队列

  • 定义:队列是一种先进先出(FIFO) 的线性表。在表一端插入,在另一端删除;

在这里插入图片描述

栈与队列的表示与实现

1.栈的表示

  • 顺序栈的表示

**顺序表示:**利用一组地址连续的存储单 元依次存放自栈底到栈顶的数据元素。 栈底一般在低地址;

在这里插入图片描述

top:指示栈顶元素位置;

base:指示栈底元素位置;

stacksize:表示栈的最大容量;

在这里插入图片描述

空栈:base == top;

栈满:top-base = stacksize;

栈的容量:stacksize= 4;

栈满时的处理方法:

1、报错,返回;

2、分配更大的空间,作为栈的存储空间,将原栈的内容移入新栈;

  • 顺序栈的表示
typedef struct{

    SElemType *base;		//栈底指针

    SElemType *top;		//栈顶指针

    int stacksize;		//栈可用最大容量

}SqStack;

SqStack S;

在这里插入图片描述

  • 链栈的表示
typedef struct StackNode{

    int data;		//数据域

    struct StackNode *next;		//指针域 

}stackNode,*LinkStack; 

LinkStack S; 
  • 栈顶指针就是链表的头指针;
  • 基本不存在满栈的情况;
  • 空栈相当于头指针指向空;
  • 插入和删除仅在栈顶处操作,不需要头结点;

在这里插入图片描述

2.顺序栈的实现

  • 初始化
Status InitStack( SqStack &S ){

    S.base =new SElemType[MAXSIZE]if( !S.base ) return OVERFLOW;		//空间分配失败

    S.top = S.base;		//栈顶指针=栈底指针

    S.stackSize = MAXSIZE;

    return OK;
}

在这里插入图片描述

  • 入栈
Status Push( SqStack &S, SElemType e){

    if( S.top- S.base== S.stacksize )		// 栈满

        return ERROR; 

    *S.top++=e;

    return OK;
}

在这里插入图片描述

  • 出栈
Status Pop( SqStack &S, SElemType e){

    if( S.top == S.base)		// 栈空

        return ERROR; 

    e= *--S.top;

    return OK;
}

在这里插入图片描述

3.链栈的实现

  • 初始化
void initStack(LinkStack &s){

    s=NULL;		//不需要头节点 
}
//无需new,因为是不带头结点的单链表
  • 栈空
int stackEmpty(LinkStack s){

    if(s==NULL)

        return ok;

    return error;
}
  • 求链栈的长度
int stackLength(LinkStack s){

    int sum=0;

    stackNode *temp=s;

    while(temp!=NULL){

        sum++;

        temp=temp->next;
    }


    return sum;
}

  • 入栈
void push(LinkStack &s,int e){

    stackNode *p=new stackNode;

    p->data=e;

    p->next=NULL;

    if(s==NULL)

        s=p;

    else{

        p->next=s;

        s=p;

    }
}

  • 出栈
void pop(LinkStack &s,int &e){

    stackNode *p=new stackNode;

    if(s==NULL){

        cout<<"栈为空,无法弹出"<<endl;

    }

    else{

        p=s;

        e=p->data;

        s=s->next;

        delete p;

        cout<<"成功弹出栈顶元素"<<endl;

    }
}

3.共享栈

  • 有两个相同类型的栈时,采用共享栈最大限度地利用实现开辟的存储空间来进行操作;
  • 怎么判空?

top0==-1;top1==MAXSIZE;

  • 怎么判满?

top1-top0 == 1;

  • 怎么进栈?

0号进栈,top0先加1再赋值;1号进栈,top1先减1再赋值;

  • 怎么出栈?

0号出栈,先赋值top0再减1;1号出栈,先赋值top1再加1;

在这里插入图片描述

队列的表示与实现

1.顺序队列的表示

#define MAXQSIZE  100		//最大队列长度 

Typedef struct{        

    ElemType data[MAXQSIZE];		//初始化的动态分配存储空间

    int *front;		//头指针     

    int *rear;		//尾指针           

}SqQueue; 

2.顺序队列的实现

  • 初始:front=rear=0;
  • J1、J2、J3依次入队 Base[rear]=x; rear++;
  • J1、J2 出队操作: x=Base[front]; front++;
  • J4、J5、J6入队 J3、J4出队;

在这里插入图片描述

是否可在队尾插入新的元素?

  • 数组大小:MAXQSIZE;
  • 若 front≠0 rear=MAXQSIZE,入队-假溢出;
  • 若 front=0 rear=MAXQSIZE,入队-真溢出;

3.循环队列的实现

  • 初始化
Status InitQueue (SqQueue &Q){

    Q.base =new QElemType[MAXQSIZE]		//分配最大容量的数组空间

        if(!Q.base) exit(OVERFLOW);		//存储分配失败

    Q.front=0;

    Q.rear=0;		//将头指针和尾指针置为0,队列为空

    return OK;
}
  • 求循环队列的长度
int QueueLength (SqQueue Q){

    return(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);

}
  • 入队
Status EnQueue(SqQueue &Q,QElemType e){

    if((Q.rear+1)%MAXQSIZE==Q.front))		//若尾指针在循环意义上加1后等于头指针,表明队满

        return ERROR;

    Q.base[Q.rear]=e;		//新元素加入队尾

    Q.rear=(Q.rear+1)%MAXQSIZE;		//队尾指针加1

    return OK;
}
  • 出队
Status DeQueue (LinkQueue &Q,QElemType &e){

    if(Q.front==Q.rear)		//队空

        return ERROR;

    e=Q.base[Q.front];		//保存队头元素

    Q.front=(Q.front+1)%MAXQSIZE;		//队头指针加1

    return OK;
}

4.链队列的表示

  • 队列结点类型
typedef struct QNode{

    QElemType data;

    struct Qnode *next;

}Qnode, *QueuePtr;
  • 链式队列管理结构
typedef struct {

    QueuePtr front;

    QueuePtr rear;

}LinkQueue;

5.链队列的实现

  • 初始化
Status InitQueue (LinkQueue &Q){

    Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));//生成新的节点作为头结点

    if(!Q.front) exit(OVERFLOW);

    Q.front->next=NULL;//头结点的指针域置空

    return OK;
}
  • 入队
Status EnQueue(LinkQueue &Q,QElemType e){

    p=(QueuePtr)malloc(sizeof(QNode));		//p=new QNode

    if(!p) exit(OVERFLOW);

    p->data=e;		//将新节点数据域置为e

    p->next=NULL; Q.rear->next=p;		//将新结点插入队尾

    Q.rear=p;		//修改队尾指针

    return OK;
}
  • 出队
Status DeQueue (LinkQueue &Q,QElemType &e){

    if(Q.front==Q.rear)

        return ERROR;		//若队为空,返回error

    p=Q.front->next;		//p指向队头元素

    e=p->data;		//e保存队头元素的值

    Q.front->next=p->next;		//修改头结点的指针域

    if(Q.rear==p)

        Q.rear=Q.front;		//元素删除,指针指向头节点

    delete p;

    return OK;
}
  • 取队头元素
Status GetHead (LinkQueue Q, QElemType &e){

    if(Q.front==Q.rear) 

        return ERROR;

    e=Q.front->next->data; //返回队头元素的值,队头指针不变

    return OK;
}

站与队列的应用

1.进制转换(十进制数159转换为八进制)

void conversion(int n){  

    stack s; 

    while (n) {  

        s.push(n % 8);n = n/8; 

    } 

    cout << "八进制数为:"; 

    while (!s.empty()){ 

        cout << s.top();s.pop();

    }

}

int main(){ 

    conversion(1234); 

    return 0;
}

tHead (LinkQueue Q, QElemType &e){

if(Q.front==Q.rear) 

    return ERROR;

e=Q.front->next->data; //返回队头元素的值,队头指针不变

return OK;

}


# 站与队列的应用

## 1.进制转换(十进制数159转换为八进制)

```c
void conversion(int n){  

    stack s; 

    while (n) {  

        s.push(n % 8);n = n/8; 

    } 

    cout << "八进制数为:"; 

    while (!s.empty()){ 

        cout << s.top();s.pop();

    }

}

int main(){ 

    conversion(1234); 

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值