前言

本篇博客依旧适合那些学过数据结构中栈及队列知识的人,不适合那些刚开始接触这个相关知识的读者,当然的话,如果你是未入门这门知识,你可以先收藏起来,等你学完这个相关知识后,可以看一下这篇博客。好了,话不多说,直接整代码吧。

栈的链式存储结构

//栈的链式存储结构
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
typedef char ElemType;
typedef int Status;
typedef struct stackNode{
    ElemType data;
    struct stackNode *next;
}stackNode,*LinkStackPtr;
typedef struct LinkStack{
    LinkStackPtr top;
    int count;
}LinkStack;
//初始化栈
Status InitStack(LinkStack *s){
    LinkStackPtr p;
    s->top=NULL;
    p->next=NULL;
    s->count=0;
}
//进栈操作
Status Push(LinkStack *s,ElemType e){
    LinkStackPtr p=(LinkStackPtr)malloc(sizeof(stackNode));
    p->data=e;
    p->next=s->top;
    s->top=p;
    s->count++;
}
//出栈操作
Status Pop(LinkStack *s,ElemType *e){
    LinkStackPtr p;
    if(StackEmpty(*s)){
        printf("栈空,无法出栈\n");
    }
    *e=s->top->data;
    p=s->top;
    s->top=s->top->next;
    free(p);
    s->count--;
    printf("出栈完毕\n");
}
//判断栈是否为空
Status StackEmpty(LinkStack *s){
    if(!s->top){
        return 1;
    }
    else{
        return 0;
    }
}
int main(){
    int choice=0;
    LinkStack s;
    while(choice!=5){
        printf("**********菜单**********\n");
        printf("|1.进栈操作   2.出栈操作|\n");
        printf("|3.初始化栈   4.判断栈是否为空|\n");
        printf("|5.退出程序|\n");
        printf("(注意:在进行所有操作时,必须提前进行初始化栈操作)\n");
        printf("请输入你的选择:");
        scanf("%d",&choice);
        switch(choice){
            case 1:{
                char e;
                printf("请输入要进栈的字符:");
                scanf("%c",&e);
                while(e!='#'){
                    Push(&s,e);
                    scanf("%c",&e);
                }
                printf("进栈操作完毕\n");
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 2:{
                char e;
                Pop(&s,&e);
                printf("出栈的字符为:%c\n",e);
                printf("出栈操作完毕\n");
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 3:{
                InitStack(&s);
                printf("初始化完成\n");
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 4:{
                int flag=StackEmpty(&s);
                if(flag){
                    printf("栈空\n");
                }
                else{
                    printf("栈不为空\n");
                }
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 5:{
                printf("程序退出\n");
                break;
            }
        }
    }
    return 0;
}

队列顺序存储结构

//队列的顺序存储结构
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<windows.h>
#include<time.h>
#define MAXSIZE 20
typedef int ElemType;
typedef int Status;
typedef struct{
    ElemType *base;
    int front;
    int rear;
}cycleQueue;
//初始化
Status initQueue(cycleQueue *q){
    q->base=(ElemType *)malloc(MAXSIZE*sizeof(ElemType));
    if(!q->base){
        printf("初始化失败\n");
        exit(0);
    }
    q->front=q->rear=0;
    printf("初始化操作完毕\n");
}
//入队操作
Status InsertQueue(cycleQueue *q,ElemType e){
    if((q->rear+1)%MAXSIZE==q->front){
        printf("队列已满,无法入队\n");
        return 0;
    }
    q->base[q->rear]=e;
    q->rear=(q->rear+1)%MAXSIZE;
    printf("入队完毕\n");
}
//出队操作
Status DeleteQueue(cycleQueue *q,ElemType *e){
    if(q->front==q->rear){
        printf("队空,出队失败\n");
        return 0;
    }
    *e=q->base[q->front];
    q->front=(q->front+1)%MAXSIZE;
    printf("出队元素值为:%d\n",*e);
    printf("出队完毕\n");
}
//销毁队列
Status DestroyQueue(cycleQueue *q){
    if(q->base){
        free(q->base);
    }
    q->base=NULL;
    q->front=q->rear=0;
    printf("销毁完毕\n");
}
int main(){
    int choice=0;
    cycleQueue q;
    while(choice!=5){
        printf("**********菜单**********\n");
        printf("|1.初始化操作   2.销毁队列|\n");
        printf("|3.入队操作     4.出队操作|\n");
        printf("|5.退出程序|\n");
        printf("(注意:在进行操作时,必须提前进行初始化操作)\n");
        printf("请输入你的选择:");
        scanf("%d",&choice);
        switch(choice){
            case 1:{
                initQueue(&q);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 2:{
                DestroyQueue(&q);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 3:{
                int e;
                printf("请输入要入队元素的值:");
                scanf("%d",&e);
                InsertQueue(&q,e);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 4:{
                int *e;
                DeleteQueue(&q,&e);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 5:{
                printf("程序退出\n");
                system("cls");
                break;
            }
        }
    }
    return 0;
}

队列的链式存储结构

//队列链式结构
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<windows.h>
#include<time.h>
typedef int Status;
typedef int ElemType;
typedef struct QNode{
    ElemType data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
    QueuePtr front,rear;
}LinkQueue;
//创建队列操作
Status initQueue(LinkQueue *q){
    q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));
    if(!q->front){
        exit(0);
    }
    q->front->next=NULL;
    printf("初始化完毕\n");
}
//入队操作
Status InsertQueue(LinkQueue *q,ElemType e){
    QueuePtr p;
    p=(QueuePtr)malloc(sizeof(QNode));
    if(p==NULL){
        printf("入队操作失败\n");
        exit(0);
    }
    p->data=e;
    p->next=NULL;
    q->rear->next=p;
    q->rear=p;
    printf("入队操作完毕\n");
}
//出队操作
Status DeleteQueue(LinkQueue *q,ElemType *e){
    QueuePtr p;
    if(q->front==q->rear){
        printf("出队操作失败\n");
        return 0;
    }
    p=q->front->next;
    *e=p->data;
    q->front->next=p->next;
    if(q->rear==p){
        q->rear=q->front;
    }
    printf("出队的元素为:%d\n",*e);
    free(p);
}
//销毁队列
Status DestroyStack(LinkQueue *q){
    while(q->front){
        q->rear=q->front->next;
        free(q->front);
        q->front=q->rear;
    }
    printf("销毁完毕\n");
}
int main(){
    int choice=0;
    LinkQueue q;
    while(choice!=5){
        printf("**********菜单**********\n");
        printf("|1.初始化操作   2.销毁操作|\n");
        printf("|3.入队操作     4.出队操作|\n");
        printf("|5.退出程序|\n");
        printf("(注意:在进行入队,出队操作时,必须提前进行初始化操作)\n");
        printf("请输入你的选择:");
        scanf("%d",&choice);
        switch(choice){
            case 1:{
                initQueue(&q);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 2:{
                DestroyStack(&q);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 3:{
                int e;
                printf("请输入要入队元素值:");
                scanf("%d",&e);
                InsertQueue(&q,e);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 4:{
                int e;
                DeleteQueue(&q,&e);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 5:{
                system("cls");
                printf("程序退出\n");
                break;
            }
        }
    }
    return 0;
}

大家可能会好奇,上面三段代码,缺少了栈的顺序存储结构。其实,我在写栈的顺序存储结构的代码时参考过其他人的代码,但是自己写完后,程序运行时,出现很多奇奇怪怪的bug,所以我在下面向大家求助一下,希望大家能够帮我找出bug。

栈的顺序存储结构

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#include<malloc.h>
#define MAXSIZE 20
typedef int Status;
typedef char ElemType;
typedef struct{
    ElemType *top;
    ElemType *base;
    int stackSize;
}sqStack;
//初始化操作
Status initStack(sqStack *s){
    s->base=(ElemType *)malloc(MAXSIZE*sizeof(ElemType));
    if(!s->base){
        printf("内存错误\n");
        exit(0);
    }
    s->top=s->base;
    s->stackSize=MAXSIZE;
    printf("创建成功\n");
}
//进栈操作
Status Push(sqStack *s,ElemType e){
    //栈满,扩展栈空间
    if(s->top-s->base>=s->stackSize){
        s->base=(ElemType *)realloc(s->base,(MAXSIZE+s->stackSize)*sizeof(ElemType));
    }
    s->top=s->base+s->stackSize;
    s->stackSize=s->stackSize+MAXSIZE;
    *(s->top)=e;
    s->top++;
}
//出栈操作
Status Pop(sqStack *s,ElemType *e){
    if(s->base==s->top){
        printf("栈空,无法出栈\n");
        return 0;
    }
    *e=*(s->top-1);
    s->top--;
    printf("出栈成功,出栈元素值为:%c\n",*e);
}
//清空栈
Status ClearStack(sqStack *s){
    s->base=s->top;
    printf("清空完毕\n");
}
//销毁栈
Status DestroyStack(sqStack *s){
    int len;
    len=s->stackSize;
    for(int i=0;i<len;i++){
        free(s->base);
        s->base++;
    }
    s->top=s->base=NULL;
    s->stackSize=0;
    printf("销毁成功\n");
}
//栈的当前容量
Status StackLen(sqStack *s){
    return (s->top-s->base);
}
int main(){
    int choice=0;
    sqStack s;
    while(choice!=7){
        printf("***************菜单***************\n");
        printf("|1.创建栈   2.清空栈|\n");
        printf("|3.销毁栈   4.返回栈容量|\n");
        printf("|5.进栈     6.出栈|\n");
        printf("|7.退出程序|\n");
        printf("请输入你的选择:");
        scanf("%d",&choice);
        switch(choice){
            case 1:{
                initStack(&s);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 2:{
                ClearStack(&s);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 3:{
                DestroyStack(&s);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 4:{
                int len=StackLen(&s);
                printf("栈的容量为:%d\n",len);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 5:{
                char e;
                printf("请输入一串字符:");
                scanf("%c",&e);
                //以#结束循环
                while(e!='#'){
                    Push(&s,e);
                    scanf("%c",&e);
                }
                getchar();
                printf("进栈操作完毕\n");
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 6:{
                char e;
                Pop(&s,&e);
                printf("程序将自动跳转到菜单页面\n");
                Sleep(1000);
                system("cls");
                break;
            }
            case 7:{
                printf("程序退出\n");
                system("cls");
                break;
            }
        }
    }
    return 0;
}

大家可以运行程序,调试一下该段代码,可以发现其中的bug。当然,我这里有一份别人写的栈的顺序存储结构代码,网址为:

希望能够帮助到大家!

参考资料

<<大话数据结构>>