数据结构实验-栈和队列

数据结构-栈和队列

四、栈的实现和应用

1、采用书上第 46 页定义的栈的顺序存储表示,编程实现栈的下列基本操作。
(1)初始化顺序栈 (2)创建顺序栈 (3)判断栈空 (4)输出顺序栈(5)取栈顶元素 (6)入栈 (7)出栈

#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
typedef int SElemType;
//存储空间初始分配量
//存储空间分配增量
typedef struct{
    SElemType *base;//在栈构造之前和销毁之后,base的值为NULL
    SElemType *top;//栈顶指针
    int stacksize;//当前已分配的存储空间,以元素为单位
}SqStack;

Status InitStack(SqStack &S){
//构造一个空栈S
    S.base =(SElemType*)malloc(STACK_INIT_SIZE* sizeof(SElemType));
    if(!S.base)exit(OVERFLOW);//存储分配失败
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
    return OK;
}//initStack

Status StackEmpty(SqStack &S){
    if(S.top==S.base)
        return TRUE;
    else
        return FALSE;
}//StackEmpty

Status GetTop(SqStack &S, SElemType &e){
    //若栈不空,则用e返回s的栈顶元素,并返回OK:否则返回ERROR
    if(S.top ==S.base) return ERROR;
    else e=*S.top;
    return OK;
}//GetTop

Status Push(SqStack &S, SElemType e){
    //插入元素e为新的栈顶元素
    if(S.top-S.base >=S.stacksize){//栈满,追加存储空间
        S.base = (SElemType* )realloc(S.base,(S.stacksize + STACKINCREMENT)* sizeof(SElemType));
        if (!S.base) exit(OVERFLOW);//存储分配失败
        S.top=S.base + S.stacksize;
        S.stacksize+=STACKINCREMENT;
    }
    S.top++;
    *S.top=e;
    S.stacksize++;
    return OK;
}//Push;

Status Pop(SqStack &S,SElemType &e){
    //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
    if(S.top==S.base) return ERROR;
    else{
        e=*S.top;
        S.top--;
        S.stacksize--;
        return OK;
    }
}//Pop

Status Stackoutput(SqStack &S){
    //若栈不空,则从栈顶到栈底依次输出数据元素,并返回OK;否则返回ERROR
    SElemType *p;
    if(S.top==S.base)return ERROR;
    p=S.top;
    while(p!=S.base){
        printf("%d ",*p);
        p--;
    }
    printf("\n");
    return OK;
}//Stackoutput

Status StackTraverse(SqStack &S){
    //若栈不空,则从栈底到栈顶依次输出数据元素,并返回OK;否则返回ERROR
    SElemType *p;
    if(S.top==S.base)return ERROR;
    p=S.base+1;
    while(p!=S.top+1){
        printf("%d ",*p);
        p++;
    }
    printf("\n");
    return OK;
}//StackTraverse

int main(void){
    int i,n,k,h,a,b;
    SqStack S;
    printf("创建一个空栈!\n");
    InitStack(S);
    printf("判断栈是否为空!\n");
    printf("StackEmpty(S)=%d\n",StackEmpty(S));
    printf("创建栈的元素个数:\n");
    scanf("%d",&n);
    printf("输入%d个入栈元素的值:\n",n);
    for(i=0;i<n;i++){
        scanf("%d",&k);
        Push(S,k);
    }
    printf("逆序输出顺序栈元素值:\n");
    Stackoutput(S);
    printf("输出顺序栈元素值:\n");
    StackTraverse(S);
    printf("输入入栈元素值:");
    scanf("%d",&h);
    Push(S,h);
    printf("输出入栈后的顺序栈元素值:\n");
    StackTraverse(S);
    Pop(S,a);
    printf("输出第1个出栈元素值:%d\n",a);
    Pop(S,a);
    printf("输出第2个出栈元素值:%d\n",a);
    printf("输出两次出栈后顺序栈元素值:");
    StackTraverse(S);
    GetTop(S,b);
    printf("输出栈顶元素值:%d\n",b);
    return 0;
}

2、采用栈的顺序存储表示,编程实现表达式中圆括号“( )”和方括号“[ ]”匹配的检验。

#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
typedef char SElemType;
//存储空间初始分配量
//存储空间分配增量
typedef struct{
    SElemType *base;//在栈构造之前和销毁之后,base的值为NULL
    SElemType *top;//栈顶指针
    int stacksize;//当前已分配的存储空间,以元素为单位
}SqStack;

Status InitStack(SqStack &S){
//构造一个空栈S
    S.base =(SElemType*)malloc(STACK_INIT_SIZE* sizeof(SElemType));
    if(!S.base)exit(OVERFLOW);//存储分配失败
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
    return OK;
}//initStack

Status StackEmpty(SqStack &S){
    if(S.top==S.base)
        return TRUE;
    else
        return FALSE;
}//StackEmpty

Status GetTop(SqStack &S, SElemType &e){
    //若栈不空,则用e返回s的栈顶元素,并返回OK:否则返回ERROR
    if(S.top ==S.base) return ERROR;
    else e=*S.top;
    return OK;
}//GetTop

Status Push(SqStack &S, SElemType e){
    //插入元素e为新的栈顶元素
    if(S.top-S.base >=S.stacksize){//栈满,追加存储空间
        S.base = (SElemType* )realloc(S.base,(S.stacksize + STACKINCREMENT)* sizeof(SElemType));
        if (!S.base) exit(OVERFLOW);//存储分配失败
        S.top=S.base + S.stacksize;
        S.stacksize+=STACKINCREMENT;
    }
    S.top++;
    *S.top=e;
    S.stacksize++;
    return OK;
}//Push;

Status Pop(SqStack &S,SElemType &e){
    //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
    if(S.top==S.base) return ERROR;
    else{
        e=*S.top;
        S.top--;
        S.stacksize--;
        return OK;
    }
}//Pop

Status Correct(SElemType str[]){
    //使用运算符栈S,当遇到'('、'['时进栈,遇到')'、']'出栈并判断出栈元素是否为相应的符号,若是则继续下一个,否则算法结束
    SqStack S;
    InitStack(S);//构造空栈
    int i,state=1;
    SElemType e;
    for(i=0;str[i]!='\0';i++){
        switch(str[i])
        {
            case '(':Push(S,str[i]);state++;break;
            case '[':Push(S,str[i]);state++;break;
            case ')':if(*S.top=='('){
                        Pop(S,e);
                        state--;
                    }
                    break;
            case ']':if(*S.top=='['){
                        Pop(S,e);
                        state--;
                    }
                    break;
        }
        if(!state)break;
    }
    if(StackEmpty(S)&&state==1)
        return OK;
    else
        return ERROR;
}//Correct

int main(void){
    SElemType str[100];
    printf("请输入带括号的表达式:\n");
    scanf("%s",str);
    if(Correct(str)==OK)
        printf("括号匹配正确!\n");
    else
        printf("括号匹配不正确!\n");
    return 0;
}

五、队列的存储表示和实现

1、采用书上第 61 页定义的队列的链式存储结构,编程实现队列的下列基本操作。
(1)构造空队列 (2)销毁队列 (3)清空队列 (4)判断队列是否为空 (5)求队列长度 (6)取队头元素 (7)插入队尾元素 (8)删除队头元素 (9)输出队列元素

//队列的链式表示
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define Status int
typedef int QElemType;
typedef struct QNode{
    QElemType data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
    QueuePtr front;//队头指针
    QueuePtr rear;//队尾指针
}LinkQueue;

Status InitQueue(LinkQueue &Q){
    //构造一个空队列
    Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
    if(!Q.front) exit(OVERFLOW);
    Q.front->next=NULL;
    return OK;
}

Status DestroyQueue(LinkQueue &Q){
    //销毁队列Q
    while(Q.front){
        Q.rear=Q.front->next;
        free(Q.front);
        Q.front=Q.rear;
    }
    return OK;
}

Status ClearQueue(LinkQueue &Q){
    //将Q清为空队列
    QueuePtr p,q;
    if(!Q.front) exit(OVERFLOW);
    p=Q.front->next;
    Q.front->next=NULL;
    Q.rear=Q.front;
    while(p)
    {
        q=p;
        p=p->next;
        free(q);
    }
    return OK;
}

Status QueueEmpty(LinkQueue Q){
    //若队列Q为空队列,则返回TRUE,否则返回FALSE
    if(Q.front==Q.rear)
        return TRUE;
    else
        return FALSE;
}

int QueueLength(LinkQueue Q){
    //返回Q的元素个数,即队列的长度
    QueuePtr p;
    int n=0;
    p=Q.front;
    while(Q.rear!=p)
    {
        n++;
        p=p->next;
    }
    return n;
}

Status GetHead(LinkQueue Q,QElemType &e){
    //若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR
    QueuePtr p;
    if(Q.front==Q.rear) return ERROR;
    p=Q.front->next;
    e=p->data;
    return OK;
}

Status EnQueue(LinkQueue &Q,QElemType e){
    //插入元素e为Q的新的队尾元素
    QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
    if(!p) exit(OVERFLOW);//存储分配失败
    p->data=e;
    p->next=NULL;
    Q.rear->next=p;
    Q.rear=p;
    return OK;
}

Status DeQueue(LinkQueue &Q,QElemType &e){
    //若队列不空,则删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR
    if(Q.front==Q.rear) return ERROR;
    QueuePtr p=Q.front->next;
    e=p->data;
    Q.front->next=p->next;
    if(Q.rear==p) Q.rear=Q.front;
    free(p);
    return OK;
}

Status QueueTraverse(LinkQueue &Q){
    //从队头到队尾依次输出队列元素的值
    QueuePtr p=Q.front->next;
    if(p==NULL)return ERROR;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
    return OK;
}

int main(void)
{
    int i,n;
    QElemType k,h,a,f;
    LinkQueue Q;
    printf("创建一个空队列!\n");
    InitQueue(Q);
    printf("判断队列是否为空!\n");
    printf("QueueEmpty(Q)=%d\n",QueueEmpty(Q));
    printf("创建队列的元素个数:\n");
    scanf("%d", &n);
    printf("输入%d个插入队列的元素的值:\n",n);
    for(i=0;i<n;i++)
    {
        scanf("%d", &k);
        EnQueue(Q, k);
    }
    printf("输出队列元素的个数:%d\n",QueueLength(Q));
    printf("输出队列元素的值:\n");
    QueueTraverse(Q);
    printf("输入插入队列的元素的值:");
    scanf("%d", &h);
    EnQueue(Q, h);
    printf("输出插入一个队列元素后队列元素的值:\n");
    QueueTraverse(Q);
    DeQueue(Q, a);
    printf("输出第1个删除的队头元素的值:%d\n", a);
    DeQueue(Q, a);
    printf("输出第2个删除的队头元素的值:%d\n", a);
    printf("输出两次删除队头元素后队列的元素值:");
    QueueTraverse(Q);
    GetHead(Q, f);
    printf("输出队头元素的值:%d\n",f);
    printf("输出队列元素的个数:%d\n",QueueLength(Q));
    printf("将Q清为空队列!\n");
    ClearQueue(Q);
    printf("输出队列元素的个数:%d\n",QueueLength(Q));
    printf("判断队列是否为空!\n");
    printf("QueueEmpty(Q)=%d\n",QueueEmpty(Q));
    return 0;
}

2、采用书上第 64 页定义的队列的顺序存储结构,编程实现循环队列的下列基本操作。
(1)构造空队列 (2)清空队列 (3)判断队列是否为空 (4)求队列长度 (5)取队头元素 (6)插入队尾元素 (7)删除队头元素 (8)输出队列元素

//队列的顺序表示:循环队列
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXQSIZE 100//最大队列长度
typedef int Status;
typedef int QElemType;
typedef struct {
    QElemType *base;//初始化的动态分配存储空间
    int front;//头指针,若队列不空,指向队列头元素
    int rear;//尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;

Status InitQueue(SqQueue &Q){
    //构造一个空队列
    Q.base=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
    if(!Q.base) exit(OVERFLOW);
    Q.front=Q.rear=0;
    return OK;
}

Status CLearQueue(SqQueue &Q)
{
    //将Q清为空队列
    if(!Q.base) exit(OVERFLOW);
    Q.front=Q.rear=0;
    return OK;
}

Status QueueEmpty(SqQueue Q)
{
    //若队列Q为空队列,则返回TRUE,否则返回FALSE
    if(Q.rear==Q.front) return TRUE;
    else return FALSE;
}

int QueueLength(SqQueue Q){
    //返回Q的元素个数,即队列的长度
    return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}

Status GetHead(SqQueue Q,QElemType &e){
    //若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR
    if(Q.front==Q.rear)return ERROR;
    e=Q.front;
    return OK;
}

Status EnQueue(SqQueue &Q,QElemType e){
    //插入元素e为新的队尾元素
    if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR;//队列满
    Q.base[Q.rear]=e;
    Q.rear=(Q.rear+1)%MAXQSIZE;
    return OK;
}

Status DeQueue(SqQueue &Q,QElemType &e){
    ///若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
    if(Q.front == Q.rear)
        return ERROR;
    e = Q.base[Q.front];
    Q.front = (Q.front + 1) % MAXQSIZE;
    return OK;
}

Status QueueTraverse(SqQueue &Q){
    int i;
    if(Q.front==Q.rear) return ERROR;
    i = Q.front;
    while(i != Q.rear){
        printf("%d ",Q.base[i]);
        i = (i + 1) % MAXQSIZE;
    }
    printf("\n");
    return OK;
}

int main(void)
{
    int i,n;
    QElemType k,h,a,f;
    SqQueue Q;
    printf("创建一个空队列!\n");
    InitQueue(Q);
    printf("判断队列是否为空!\n");
    printf("QueueEmpty(Q)=%d\n",QueueEmpty(Q));
    printf("创建队列的元素个数:\n");
    scanf("%d", &n);
    printf("输入%d个插入队列的元素的值:\n",n);
    for(i=0;i<n;i++)
    {
        scanf("%d", &k);
        EnQueue(Q, k);
    }
    printf("输出队列元素的个数:%d\n",QueueLength(Q));
    printf("输出队列元素的值:\n");
    QueueTraverse(Q);
    printf("输入插入队列的元素的值:");
    scanf("%d", &h);
    EnQueue(Q, h);
    printf("输出插入一个队列元素后队列元素的值:\n");
    QueueTraverse(Q);
    DeQueue(Q, a);
    printf("输出第1个删除的队头元素的值:%d\n", a);
    DeQueue(Q, a);
    printf("输出第2个删除的队头元素的值:%d\n", a);
    printf("输出两次删除队头元素后队列的元素值:");
    QueueTraverse(Q);
    GetHead(Q, f);
    printf("输出队头元素的值:%d\n",f);
    printf("输出队列元素的个数:%d\n",QueueLength(Q));
    printf("将Q清为空队列!\n");
    CLearQueue(Q);
    printf("输出队列元素的个数:%d\n",QueueLength(Q));
    printf("判断队列是否为空!\n");
    printf("QueueEmpty(Q)=%d\n",QueueEmpty(Q));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kethy__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值