前言
本文主要讲解了栈和队列的内容,给出了它们的顺序结构实现方式和链式结构实现方式
并给出了它的操作函数的C语言实现
一、栈和队列概述
栈和队列的数据处理方式还是很简单的:
1.栈始终保持元素后进先出(LIFO)的原则
2.队列始终保持元素先进先出(FIFO)的原则
同时还有一个注意点:
栈和队列的弹栈或者出队都会删除相应的元素;而访问操作,不会删除相应元素
二、栈
1.顺序结构栈
#include<stdio.h>
#define maxn 100
typedef struct zhan
{
int top1;
int top2;
int number1;
int number2;
int a[maxn];
};
void isempty(zhan * list,int judge)
{
if(judge)
{
if(list->number1<=0)
{
printf("栈1为空\n");
}
else
{
printf("栈1不空\n");
}
}
else
{
if(list->number2<=0)
{
printf("栈2为空\n");
}
else
{
printf("栈2不空\n");
}
}
}
void chushihua(zhan *list)
{
list->top1=-1;
list->top2=maxn;
list->number1=0;
list->number2=0;
}
void push(zhan *list,int judge,int n)
{
if(list->top1+1==list->top2) printf("满栈,失败\n");
if(judge)
{
list->number1=list->number1+1;
list->top1=list->top1+1;
list->a[list->top1]=n;
}
else
{
list->number2=list->number2+1;
list->top2=list->top2-1;
list->a[list->top2]=n;
}
}
int gettop(zhan *list,int judge)
{
if(judge)
{
if(list->number1==0)
{
printf("栈1为空\n");
}
else
{
return list->a[list->top1];
}
}
else
{
if(list->number2==0)
{
printf("栈2为空\n");
}
else
{
return list->a[list->top2];
}
}
}
void pritop(zhan *list,int judge)
{
if(judge)
{
if(list->number1==0)
{
printf("栈1为空\n");
}
else
{
printf("%d\n",list->a[list->top1]);
}
}
else
{
if(list->number2==0)
{
printf("栈2为空\n");
}
else
{
printf("%d\n",list->a[list->top2]);
}
}
}
void popup(zhan *list,int judge)
{
if(judge)
{
if(list->number1==0)
{
printf("栈1为空\n");
}
else
{
list->a[list->top1]=0;
list->top1=list->top1-1;
list->number1=list->number1+1;
}
}
else
{
if(list->number2==0)
{
printf("栈2为空\n");
}
else
{
list->a[list->top2]=0;
list->top2=list->top2+1;
list->number2=list->number2+1;
}
}
}
int main()
{
zhan x;
chushihua(&x);
isempty(&x,0);
isempty(&x,1);
for(int i=1;i<10;i++)
{
push(&x,0,2*i);
}
for(int i=1;i<10;i++)
{
push(&x,1,3*i);
}
isempty(&x,0);
isempty(&x,1);
for(int i=1;i<10;i++)
{
pritop(&x,0);
pritop(&x,1);
printf("%d %d\n",gettop(&x,0)+1,gettop(&x,1)+1);
popup(&x,0);
popup(&x,1);
}
isempty(&x,0);
isempty(&x,1);
}
2.链表结构栈
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node* next;
};
typedef struct zhan
{
node body;
int number;
};
int isempty(zhan *list)
{
if(list->number==0)
return 1;
else
return 0;
}
zhan *chushihua()
{
zhan *a;
a=(zhan *)malloc(sizeof(zhan));
a->number=0;
a->body.next=NULL;
return a;
}
void push(zhan *list,int n)
{
if(list->number==0)
{
node *s;
s=(node*)malloc(sizeof(node));
list->body.next=s;
s->data=n;
s->next=NULL;
list->number=list->number+1;
}
else if(list->number<0)
{
printf("栈初始化错误\n");
}
else
{
node *s;
s=(node*)malloc(sizeof(node));
s->next=list->body.next;
list->body.next=s;
s->data=n;
list->number=list->number+1;
}
}
int gettop(zhan *list)
{
if(list->number==0)
{
printf("栈为空,获取失败\n");
return 223333;
}
else
{
int temp;
temp=list->body.next->data;
return temp;
}
}
void pritop(zhan *list)
{
if(list->number==0)
{
printf("栈为空,获取失败\n");
}
else
{
int temp;
temp=list->body.next->data;
printf("%d\n",temp);
}
}
void popup(zhan *list)
{
if(list->number==0)
{
printf("栈为空,弹出失败\n");
}
else if(list->number==1)
{
free(list->body.next);
list->number=list->number-1;
}
else
{
node *per;
list->body.next=list->body.next->next;
per=list->body.next;
free(per);
list->number=list->number-1;
}
}
void destroy(zhan *list)
{
free(list);
printf("销毁成功\n");
}
int main()
{
zhan *a;
a=chushihua();
int b[4]={5154351,4848,8444,55};
for(int i=0;i<4;i++)
{
push(a,b[i]);
}
if(!isempty(a))
{
printf("栈不空\n");
}
else
{
printf("栈为空\n");
}
for(int i=0;i<4;i++)
{
pritop(a);
printf("%d\n",gettop(a)+1);
popup(a);
}
popup(a);
if(!isempty(a))
{
printf("栈不空\n");
}
else
{
printf("栈为空\n");
}
destroy(a);
return 0;
}
三、队列
由于队列的规则是先进先出,形象点讲就是元素从队尾加入,然后从队首出去。如果在内存上仅仅是加尾去头的话,对于数组这样的顺序存储结构十分的困难,因此我们需要编写循环队列,来应对顺序存储结构
1.顺序结构队列
#include<stdio.h>
#define maxn 10
typedef struct duilie
{
int top;
int tail;
int a[maxn];
int number;
int judge;
};
void chushihua(duilie *list)
{
list->top=0;
list->tail=-1;
list->number=0;
list->judge=0;
}
void isempty(duilie *list)
{
if((list->top%maxn)==(list->tail%maxn)||list->tail==-1)
{
printf("队列为空\n");
}
else
{
printf("队列不为空\n");
}
}
void push(duilie *list,int n)
{
if(list->judge==1&&(list->tail+1)%maxn==(list->top%maxn))
{
printf("队列为满,无法插入\n");
}
else
{
list->tail=list->tail+1;
list->a[list->tail%maxn]=n;
list->number=list->number+1;
if((list->tail+1)%maxn==(list->top%maxn))
{
list->judge=1;
}
}
}
void pritop(duilie *list)
{
if((list->top%maxn)==(list->tail%maxn))
{
printf("队列空\n");
}
else
{
printf("%d\n",list->a[list->top%maxn]);
}
}
int gettop(duilie *list)
{
if((list->top%maxn)==(list->tail%maxn))
{
printf("队列空\n");
return 2233333;
}
else
{
return list->a[list->top%maxn];
}
}
void popup(duilie *list)
{
if((list->top%maxn)==(list->tail%maxn))
{
printf("队列空\n");
}
else
{
list->top=list->top+1;
list->number=list->number-1;
}
}
int main()
{
duilie x;
isempty(&x);
chushihua(&x);
printf("%d %d\n",x.tail,x.top);
for(int i=0;i<11;i++)
{
push(&x,2*i);
}
for(int i=0;i<8;i++)
{
pritop(&x);
popup(&x);
printf("%d %d\n",x.tail,x.top);
}
for(int i=0;i<10;i++)
{
push(&x,3*i);
printf("%d %d\n",x.tail,x.top);
}
for(int i=0;i<10;i++)
{
pritop(&x);
popup(&x);
printf("%d %d\n",x.tail,x.top);
}
return 0;
}
2.链式结构队列
#include<stdio.h>
#include<stdlib.h>
typedef struct body
{
int value;
struct body *next;
};
body *init()
{
body *first=(body*)malloc(sizeof(body));
first->next=NULL;
first->value=0;
printf("创建成功\n");
return first;
}
void isemp(body *first)
{
if(first->next==NULL||first==NULL)
{
printf("循环队列为空\n");
}
else printf("循环队列不为空\n");
}
int length(body *first)
{
if(first->next==NULL)
{
return 0;
}
else
{
return first->value;
}
}
int gettop(body *first)
{
if(first->next==NULL)
{
printf("循环队列为空表,取值无效\n");
return 223333;
}
else
{
int temp;
body *per;
per=first->next;
return per->value;
}
}
void printtop(body *first)
{
if(first->next==NULL)
{
printf("循环队列为空表,取值无效\n");
}
else
{
int temp;
body *per;
per=first->next;
printf("%d\n",per->value);
}
}
void push(body* first,int value1)
{
body *per;
per=first;
for(int k=1;k<first->value;k++)
{
per=per->next;
}
body *temp;
temp=(body*)malloc(sizeof(body));
temp->value=value1;
temp->next=first->next;
first->next=temp;
per->next=temp;
printf("入队成功\n");
first->value=first->value+1;
}
void popuptop(body *first)
{
body* per;
per=first;
if(per->next==NULL)
{
printf("出队失败\n");
}
else
{
per=first;
for(int k=1;k<first->value;k++)
{
per=per->next;
}
body *s;
s=first->next;
per->next=first->next->next;
first=per->next;
free(s);
first->value=first->value-1;
printf("出队成功\n");
}
}
void destroy(body *first)
{
body* per;
first->value=0;
per=first->next;
for(int i=1;i<=first->value;i++)
{
body* temp;
temp=per;
per=per->next;
free(temp);
}
first->next=NULL;
printf("销毁完成\n");
}
总结
文章不妥错误之处请大家包涵和指正
文章大量使用了链表的相关内容,大家可以看文章:
《算法导论》学习(十二)----链表(C语言)