栈又称为堆栈,是一种特殊的线性结构。
栈的定义及运算
栈的定义
后进先出的线性结构
栈的几个术语
(1)进栈。插入元素
(2)出栈。删除元素
(3)栈顶和栈底。允许进行插入和删除操作的一端称为栈顶,另一端为栈底。
(4)栈顶元素。处于栈顶位置的数据元素。
(5)栈底元素。处于栈底位置的数据元素
(6)空栈,没有数据元素。
栈的特性
(1)先进后出的线性表,简称LIFO表
(2)栈是一种特殊的线性表,其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行。
栈的存储和实现
顺序栈
由于栈是操作受限的线性表,因此与线性表类似。
(1)顺序栈的定义
栈的顺序存储结构称为顺序栈,顺序栈是用一个预设的足够长的一维数组和一个记录栈顶元素位置的变量。
(2)顺序栈的类型定义
#define MAX 100
typedef int Datatype;
typedef struct{
Datatype data[MAX];
int top;
}SeqStack;
(3)顺序栈的初始化
void InitStack(SeqStack *s){
s->top=-1;
if(s->top==-1){
printf("创建成功!!");
}else{
printf("创建失败!!");
exit(1);
}
}
(4)进栈操作
void Pust(SeqStack *s){
int i,j,l;
i=j=0;
l=s->top;
s->top=0;
for(i=0;i<l;){
if(l==-1){
break;
}
s->top++;
i++;
}
if(s->top==MAX-1){
printf("进栈失败栈满!!");
exit(1);
}else{
printf("输入Start开始进栈,End结束进栈:");
char p[MAX];
static char Star[]={"Start"};
static char End[]={"End"};
char *q;
gets(p);
q=p;
while(strcmp(q,Star)!=0){
if(strcmp(q,End)==0){
break;
}
printf("输入Start开始进栈:");
memset(p, 0, sizeof p);
gets(p);
q=p;
}
if(strcmp(q,Star)==0){
printf("\n输入进栈元素:");
memset(p, 0, sizeof p);
gets(p);
q=p;
}
while(strcmp(q,End)!=0){
printf("\n输入进栈元素:");
s->data[s->top]=atoi(q);
s->top++;
j++;
memset(p, 0, sizeof p);
gets(p);
q=p;
continue;
}
}
if(l+j==j&&j!=0){
printf("进栈失败!!");
}else if(j!=0){
printf("进栈成功!!");
l=s->top;
printf("\n栈中元素为:");
for(i=0;i<l;i++){
printf("%5d",s->data[i]);
}
}else{
printf("你确定不需要进栈?");
}
}
(5)出栈操作
void Pop(SeqStack *s){
int i,j,l;
int x;
i=j=0;
l=s->top;
for(i=0;i<l;){
if(l==-1){
printf("栈空!不能出栈!!");
exit(1);
}
i++;
}
if(l!=-1){
printf("输入Start开始出栈,End结束出栈:");
char p[MAX];
static char Star[]={"Start"};
static char End[]={"End"};
char *q;
gets(p);
q=p;
while(strcmp(q,Star)!=0){
if(strcmp(q,End)==0){
break;
}
printf("输入Start开始出栈:");
memset(p, 0, sizeof p);
gets(p);
q=p;
}
if(strcmp(q,Star)==0){
printf("\n输入出栈元素:");
memset(p, 0, sizeof p);
gets(p);
q=p;
}
l=s->top;
while(strcmp(q,End)!=0){
if(s->data[l-1]!=atoi(p)){
printf("\n不符合出栈规则!!请重新输入:");
gets(p);
continue;
}
if(s->data[l-1]==atoi(p)){
x=s->data[l-1];
s->data[l-1]=s->data[s->top];
s->top--;
l=s->top;
printf("\n输入出栈元素:");
memset(p, 0, sizeof p);
gets(p);
q=p;
j++;
continue;
}
}
}
if(i+j==j&&j!=0){
printf("出栈失败!!");
}else if(j!=0){
printf("出栈成功!!");
l=s->top;
if(l==0){
printf("栈内以无元素以全部出栈。");
}else{
printf("\n栈中元素为:");
for(i=0;i<l;i++){
printf("%5d",s->data[i]);
}
}
}else{
printf("你没有出栈操作!!");
}
}
链栈
(1)链栈的定义
用链式存储结构实现的栈称为链栈
(2)链栈类型的定义
typedef int DataType;
typedef struct linknode{
DataType data;
struct linknode *next;
}Chainstack;
(3)链栈的初始化
Chainstack *InitList(){
Chainstack *s;
s=NULL;
if(s==NULL){
printf("创建成功!");
}else{
printf("创建失败!");
exit(1);
}
}
(4)进栈及出栈操作
- 进栈
Chainstack *Push(Chainstack *s){
int js(Chainstack *s);
Chainstack *p;
Chainstack *t;
int k,j;
k=j=0;
k=js(s);
char q[50];
static char Start[]="Start";
static char End[]="End";
printf("输入Start开始进栈,输入End结束:");
gets(q);
while(strcmp(q,Start)!=0){
if(strcmp(q,End)==0){
printf("你没有进行进栈操作!");
break;
}
printf("\n输入错误!输入Start开始进栈:");
memset(q,0,sizeof q);
gets(q);
}
if(strcmp(q,Start)==0){
printf("\n输入进栈元素:");
memset(q,0,sizeof q);
gets(q);
}
while(strcmp(q,End)!=0){
p=(Chainstack *)malloc(sizeof(Chainstack));
p->data=atoi(q);
p->next=s;
s=p;
printf("\n输入进栈元素:");
memset(q,0,sizeof q);
gets(q);
j++;
}
if(k+j==j&&j==0){
printf("进栈失败!");
}
else if(j!=0){
printf("进栈成功!");
t=s;
for(k=0;k<j;k++){
printf("%5d",t->data);
t=t->next;
}
}
return s;
}
- 出栈
Chainstack *Pop(Chainstack *s){
int k,j;
k=j=0;
k=js(s);
Chainstack *t;
int x;
Chainstack *p;
if(Judge(s)==0){
printf("栈为空无法删除!!");
return NULL;
}
char q[50];
static char Start[]="Start";
static char End[]="End";
printf("\n输入Start开始出栈,输入End结束:");
gets(q);
while(strcmp(q,Start)!=0){
if(strcmp(q,End)==0){
printf("你没有进行出栈操作!");
break;
}
printf("\n输入错误!输入Start开始出栈:");
memset(q,0,sizeof q);
gets(q);
}
if(strcmp(q,Start)==0){
memset(q,0,sizeof q);
}
while(strcmp(q,End)!=0){
printf("\n请输入出栈元素:");
gets(q);
x=atoi(q);
if(s->data==x){
j++;
x=s->data;
p=s;
s=s->next;
free(p);
}else{
if(strcmp(q,End)!=0){
printf("\n不符合出栈规则!");
continue;
}
}
}
if(k+j==j&&j==0){
printf("出栈失败!");
}
else if(j!=0){
printf("\n出栈成功!");
printf("\n出栈后的栈中元素为:");
t=s;
for(k=0;k<j;k++){
printf("%5d",t->data);
t=t->next;
}
}
return s;
}
(5)取栈顶元素
void Topofstack(Chainstack *s){
int x;
if(Judge(s)==0){
printf("栈空!取值失败!");
exit(1);
}else{
printf("栈顶元素为:");
x=s->data ;
printf("%5d",x);
}
}