第三章 栈 和 队 列



1、栈是限仅在表进行插入和删除操作的线性表

我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。

栈的插入操作叫做进栈,也称压栈、入栈。删除操作叫做出栈,也称弹栈。

2、栈的应用——递归

我们把一个直接调用自己或通过一系列调用语句间接地调用自己的函数,称为递归函数 

//栈的顺序存储结构,数组实现
typedef struct {
    ElemType data[MAXSIZE];
    int top;        //用于栈顶指针
}SqStack;
Status Init_SqStack(SqStack *S); //建立空栈(清空栈)
Status Destroy_SqStack(SqStack *S); //销毁栈,S = NULL
ElemType GetTop_SqStack(SqStack S); //返回栈顶元素
int Length_SqStack(SqStack S);  //返回栈中元素个数,S.top
int isEmpty_SqStack(SqStack S); //栈为空,返回TRUE;反之返回FALSE;
Status Push_SqStack(SqStack *S, ElemType e);    //入栈
ElemType Pop_SqStack(SqStack *S);   //出栈

//初始化栈,即建立空栈
Status Init_SqStack(SqStack *S) {
    S->top = 0;
    return OK;
}

//返回栈顶元素
ElemType GetTop_SqStack(SqStack S) {
    if(S.top) return S.data[S.top];
    return ERROR;
}

//栈为空,返回TRUE;反之返回FALSE;
int isEmpty_SqStack(SqStack S) {
    if(S.top) return FALSE;
    return TRUE;
}

//入栈
Status Push_SqStack(SqStack *S, ElemType e) {
    if(S->top<MAXSIZE) {
        S->data[S->top++] = e;
        return OK;
    }
    return ERROR;
}

//出栈
ElemType Pop_SqStack(SqStack *S) {
    if(S->top) return S->data[--S->top];
    return ERROR;
}

//栈的链式存储结构
typedef struct StackNode {    //节点结构
    ElemType data;
    struct StackNode *next;
}StackNode, *LinkStackPtr;
typedef struct LinkStack {      //链栈结构
    LinkStackPtr top;           //栈顶指针
    int length;
}LinkStack;
Status Init_LinkStack(LinkStack *S); //建立空栈(清空栈)
Status Destroy_LinkStack(LinkStack *S); //销毁栈,S = NULL
ElemType GetTop_LinkStack(LinkStack S); //返回栈顶元素
Status Push_LinkStack(LinkStack *S, ElemType e);    //入栈
ElemType Pop_LinkStack(LinkStack *S);   //出栈

//初始化栈,即建立带有头结点的空栈
Status Init_LinkStack(LinkStack *S) {
    S->top = (LinkStackPtr)malloc(sizeof(StackNode));
    S->top->next = NULL;
    S->length = 0;
    return OK;
}

//返回栈顶元素
ElemType GetTop_LinkStack(LinkStack S) {
    if(S.length) return S.top->data;
    return ERROR;
}

//入栈
Status Push_LinkStack(LinkStack *S, ElemType e) {
    LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
    p->data = e;
    p->next = S->top;
    S->top = p;
    S->length++;
    return OK;
}

//出栈
ElemType Pop_LinkStack(LinkStack *S) {
    LinkStackPtr p;
    ElemType e;
    if(S->length) {
        p = S->top;
        S->top = p->next;
        e = p->data;
        free(p);
        S->length--;
        return e;
    }
    return ERROR;
}
        
队列

1、队列queue只允许在一端进行插入操作,而在另一端进行删除操作的线性表(先进先出FIFO

队列是一种先进先出(First In First Out)的线性表,简称FIFO

2、把队列的这种头尾相接的顺序存储结构称为循环队列。

Ø 队列空则满足rear == front

Ø 队列满则满足(rear+1)%QueueSize == front

Ø  队列长度为 :(rear-front+QueueSize%QueueSize

//循环队列的顺序存储结构
typedef struct {
    ElemType data[MAXSIZE];
    int front;      //头指针
    int rear;       //尾指针,若队列不空,指向队列尾元素下一个位置
} SqQueue;
Status Init_SqQueue(SqQueue *Q);    //初始化,建立空队列Q
int isEmpty_SqQueue(SqQueue Q);     //队列为空返回TRUE;否则返回FALSE素
int Length_SqQueue(SqQueue Q);      //返回队列元素个数
ElemType GetElem_SqQueue(SqQueue Q);//返回队头元素
Status EnQ_SqQueue(SqQueue *Q, ElemType e);//将元素e插入队尾
ElemType DeQ_SqQueue(SqQueue *Q);   //删除并返回队头元素

//初始化,建立空队列Q
Status Init_SqQueue(SqQueue *Q) {
    Q->front = 0;
    Q->rear = 0;
    return OK;
}

//队列为空返回TRUE;否则返回FALSE素
int isEmpty_SqQueue(SqQueue Q) {
    if(Q.front == Q.rear) return TRUE;
    return FALSE;
}

//返回队列元素个数
int Length_SqQueue(SqQueue Q) {
    return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}

//返回队头元素
ElemType GetElem_SqQueue(SqQueue Q) {
    if(!isEmpty_SqQueue(Q))
        return Q.data[Q.front];
    return ERROR;
}

//将元素e插入队尾
Status EnQ_SqQueue(SqQueue *Q, ElemType e) {
    if((Q->rear+1)%MAXSIZE == Q->front)
        return ERROR;
    Q->data[Q->rear] = e;
    Q->rear = (Q->rear+1) % MAXSIZE;
    return OK;
}

//删除并返回队头元素
ElemType DeQ_SqQueue(SqQueue *Q) {
    if(isEmpty_SqQueue(*Q))
        return ERROR;
    ElemType e;
    e = Q->data[Q->front];
    Q->front = (Q->front + 1) % MAXSIZE;
    return e;
}

3、 队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们把它简称为链队列。   
//循环队列的链式存储结构
typedef struct QNode {  //结点结构
    ElemType data;
    struct QNode *next;
}QNode, *QueuePtr;
typedef struct {
    QueuePtr front, rear;//front为队列头结点,数据域无效,指针域为指向第一个元素的指针
    int length;          //rear为尾指针, length为队列长度
} LinkQueue;
Status Init_LinkQueue(LinkQueue *Q);    //初始化,建立空队列Q
ElemType GetElem_LinkQueue(LinkQueue Q);//返回队头元素
Status EnQ_LinkQueue(LinkQueue *Q, ElemType e);//将元素e插入队尾
ElemType DeQ_LinkQueue(LinkQueue *Q);   //删除并返回队头元素

//初始化,建立空队列Q
Status Init_LinkQueue(LinkQueue *Q) {
    Q->front = (QueuePtr)malloc(sizeof(QNode));
    Q->rear = Q->front;
    Q->front->next = NULL;
    Q->length = 0;
    return OK;
}

//返回队头元素
ElemType GetElem_LinkQueue(LinkQueue Q) {
    if(Q.length)
        return Q.front->next->data;
    return ERROR;
}

//将元素e插入队尾
Status EnQ_LinkQueue(LinkQueue *Q, ElemType e) {
    QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
    if(!s) exit(OVERFLOW);
    s->data = e;
    s->next = NULL;
    Q->rear->next = s;
    Q->rear = s;
    Q->length++;
    return OK;
}

//删除并返回队头元素
ElemType DeQ_LinkQueue(LinkQueue *Q) {
    if(Q->length == 0)
        return ERROR;
    ElemType e;
    QueuePtr p;
    p = Q->front->next;
    e = p->data;
    Q->front->next = p->next;
    free(p);
    Q->length--;
    return e;
}

               

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值