前言
本篇博客依旧适合那些学过数据结构中栈及队列知识的人,不适合那些刚开始接触这个相关知识的读者,当然的话,如果你是未入门这门知识,你可以先收藏起来,等你学完这个相关知识后,可以看一下这篇博客。好了,话不多说,直接整代码吧。
栈的链式存储结构
//栈的链式存储结构
#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。当然,我这里有一份别人写的栈的顺序存储结构代码,网址为:
希望能够帮助到大家!
参考资料
<<大话数据结构>>