栈在一些复杂算法里比较常见,其单入单出的概念比较好理解,但是砸代码上还是和单纯的链表和数组有一些区别的,所以我做了关于顺序表和链表的两种笔记,大家可以做一个参考
话不多说,首先是顺序表:
初始化
typedef char Element ;//定义Element类型为char,方便整体更改
typedef struct Node
{
Element data[Maxsize];//栈里的元素数组,保存了最多Maxsize个元素,因为数组所对应的是地址,所以更改数组元素的时候需要输入指针形式的结构体
int top;//用于确定栈顶的指针;
}Node;
void chushihua(Node *s)//只要在函数里输入Node即可判断
{
s->top=-1;//使栈里一开始的top为-1
}
判空
int panduan(Node s)//只是判断top,没有要改变数组的值所以不用输入地址形式的指针
{
if(s.top==-1) return 0;
else return 1;
}
压栈(即入栈)
void yazhan(Node *s,Element e)//输入顺序表的地址和要入栈的元素;
{
if(s->top== Maxsize-1) //先判断是否栈满
{
printf("栈满,不能入栈");
return;
}
else
{
s->data[++s->top]=e;//先给top值+1(提升栈顶),然后在栈顶之下的存储空间上赋予e的值;
printf("%c",e);
}
}
出栈
void chuzhan(Node *s,Element *e)//把top上的值带到另一个地址上,然后只需要top-1就可以了(所以要先出栈,再改top的值)
//这样再入栈添加时,就会直接覆盖此刻的top值,相当于把此刻出栈的值弹出了
{
if(s->top== -1) //先判断是否栈满
{
printf("栈空,不能出栈");
return;
}
else
{
*e = s->data[s->top--];//先出栈,top再减一
printf("%c 成功出栈 \n ",*e);
}
}
读取栈顶元素(主要是为了检验用的)
void duqu(Node s)
{
int t;
t=panduan(s);
if(t==0)
{
printf("栈为空,不能读取栈顶元素");//先判空
return;
}
else
{
printf("栈顶元素为:%c \n ",s.data[s.top]);//读出栈顶元素,然后输出;可以用来验证出栈和入栈元素;
}
}
还是老规矩,函数名都是拼音,大家应该可以看懂叭
最后主函数
int main()
{
Node s;
chushihua(&s);//初始化栈;
int t;
if(s.top== -1) //先判断是否栈满
{
printf("栈空 \n ");
}
else printf("%d 栈不为空 \n ",s.top);
printf("依次进栈元素为:");
yazhan(&s,'a');//a,b,c,d,e依次进栈;
yazhan(&s,'b');//注意此处字符串应该为单引号;
yazhan(&s,'c');
yazhan(&s,'d');
yazhan(&s,'e');
printf(" \n ");
t=panduan(s);//再次判空;此处应该为不空;
if(t==0) printf("栈为空 \n ");
else printf("栈不为空 \n ");
duqu(s);//读取栈顶元素后,再依次出栈,然后读取栈顶元素,应该是随着出栈的变化而变化的;
Element x;
chuzhan(&s,&x);
duqu(s);//每一次都读一下栈顶元素,应该每次出栈之后都不一样;
chuzhan(&s,&x);
duqu(s);
chuzhan(&s,&x);
duqu(s);
chuzhan(&s,&x);
duqu(s);
chuzhan(&s,&x);
t=panduan(s);
if(t==0) printf("栈为空 \n ");
else printf("栈不为空 \n ");//最后判空一下,发现栈为空
return 0;
}
完整代码如下
#include<stdio.h>
#include<stdlib.h>
#define Maxsize 100
//数组形式的栈即顺序存储(不用定义结构体里的next指针,因为数组本身就具有顺序性,会比较方便)
//但是仍需要定义动态指针,来更改top的值(栈顶的值)
//【初始化】
typedef char Element ;//定义Element类型为char,方便整体更改
typedef struct Node
{
Element data[Maxsize];//栈里的元素数组,保存了最多Maxsize个元素,因为数组所对应的是地址,所以更改数组元素的时候需要输入指针形式的结构体
int top;//用于确定栈顶的指针;
}Node;
void chushihua(Node *s)//只要在函数里输入Node即可判断
{
s->top=-1;//使栈里一开始的top为-1
}
//【判空】
int panduan(Node s)//只是判断top,没有要改变数组的值所以不用输入地址形式的指针
{
if(s.top==-1) return 0;
else return 1;
}
//【压栈】
void yazhan(Node *s,Element e)//输入顺序表的地址和要入栈的元素;
{
if(s->top== Maxsize-1) //先判断是否栈满
{
printf("栈满,不能入栈");
return;
}
else
{
s->data[++s->top]=e;//先给top值+1(提升栈顶),然后在栈顶之下的存储空间上赋予e的值;
printf("%c",e);
}
}
//【出栈】
void chuzhan(Node *s,Element *e)//把top上的值带到另一个地址上,然后只需要top-1就可以了(所以要先出栈,再改top的值)
//这样再入栈添加时,就会直接覆盖此刻的top值,相当于把此刻出栈的值弹出了
{
if(s->top== -1) //先判断是否栈满
{
printf("栈空,不能出栈");
return;
}
else
{
*e = s->data[s->top--];//先出栈,top再减一
printf("%c 成功出栈 \n ",*e);
}
}
//【读取栈顶元素】
void duqu(Node s)
{
int t;
t=panduan(s);
if(t==0)
{
printf("栈为空,不能读取栈顶元素");//先判空
return;
}
else
{
printf("栈顶元素为:%c \n ",s.data[s.top]);//读出栈顶元素,然后输出;可以用来验证出栈和入栈元素;
}
}
//【主函数】
int main()
{
Node s;
chushihua(&s);//初始化栈;
int t;
if(s.top== -1) //先判断是否栈满
{
printf("栈空 \n ");
}
else printf("%d 栈不为空 \n ",s.top);
printf("依次进栈元素为:");
yazhan(&s,'a');//a,b,c,d,e依次进栈;
yazhan(&s,'b');//注意此处字符串应该为单引号;
yazhan(&s,'c');
yazhan(&s,'d');
yazhan(&s,'e');
printf(" \n ");
t=panduan(s);//再次判空;此处应该为不空;
if(t==0) printf("栈为空 \n ");
else printf("栈不为空 \n ");
duqu(s);//读取栈顶元素后,再依次出栈,然后读取栈顶元素,应该是随着出栈的变化而变化的;
Element x;
chuzhan(&s,&x);
duqu(s);//每一次都读一下栈顶元素,应该每次出栈之后都不一样;
chuzhan(&s,&x);
duqu(s);
chuzhan(&s,&x);
duqu(s);
chuzhan(&s,&x);
duqu(s);
chuzhan(&s,&x);
t=panduan(s);
if(t==0) printf("栈为空 \n ");
else printf("栈不为空 \n ");//最后判空一下,发现栈为空
return 0;
}
运行出来如果无误的话应该是
当然了,这次代码是我自己码的了,所以如果有什么问题的话,大家也多多指正(>~<)
(下节是栈链,顺便总结一下这两者的区别~等会见)