接着上一次的顺序栈,今天我记一下链栈,因为我也是刚学不久,有些地方也稍稍理解不了,所以,一起共勉。我会用我自己结合教材上画的图,争取跟代码一起结合,用文字和图最大化的解释代码,这样的话大家就可以很容易的懂了。在看本文之前,建议初学者们先看看书上的链栈的解释,这里我将不会再仔细的说明了。假如你先看书再来看文章,效果会很不错。废话不多说了,大神勿喷,有错误请在下方评论区指出,让我和后来的初学者们一起进步。
# include<stdio.h>
# include<stdlib.h>//malloc free 的头文件 或者用# include<malloc.h>
# define FALSE 0
# define TRUE 1
typedef struct node//定义节点
{
int data;
struct node * next;
} stacknode;
typedef struct//定义一个链栈
{
stacknode * top; //这是一个链栈的指针 就是一个箭头 名为top 专门指向一个有着数据域和指针域的类型节点
int count;//计数器 记录链栈的元素个数
} linkstack;
图示如下:
void init(linkstack * s);//初始化
int em(linkstack * s);//判断是否为空(链栈一般不会为满)
int push(linkstack * s,int a);//入栈
int pop(linkstack * s,int * a);//出栈
int ding(linkstack * s,int * a);//只取栈顶元素(不对栈有任何操作)
int length(linkstack * s,int *a);//取链栈长度
void init(linkstack * s)
{
s->top=NULL;//该指针箭头指向为空
s->count=0;//初始化时长度为零
}
图示如下:
int em(linkstack * s)
{
return (s->top==NULL? TRUE:FALSE);
}
int push(linkstack * s,int a)
{
stacknode * p=(stacknode *)malloc(sizeof(stacknode));//申请生成新节点
if(p==NULL)//申请不成功
return FALSE;
else
{
p->data=a;//挂载
p->next=s->top;//新节点的指针域指向原栈顶节点
s->top=p;//栈顶指针指向新节点
s->count++;
return TRUE;
}
}
图示如下:
大家思考一下,上面三行代码的顺序不可以乱,这是为什么呢?
int pop(linkstack * s,int *a)
{
stacknode * p;//定义临时变量存储节点 我也挺想不通为啥要弄个临时节点
if(em(s))
return FALSE;
else
{
p=s->top;//把节点赋给临时节点 //其实这时p与s->top已经融为一体了(为栈顶取了新名字)
* a =p->data;//将栈顶元素的值发送出去
s->top=p->next;
s->count--;
free(p);//所以free(p)就是free(s->top)
return TRUE;
}
}
图示如下:
int ding(linkstack * s,int * a)
{
if(em(s))
return FALSE;
else
{
* a=s->top->data;
return TRUE;
}
}
int length(linkstack * s)
{
return s->count;
}
int main(void)
{
linkstack s;
int a,b,c,d;
init(&s);
push(&s,1);
push(&s,12);
push(&s,15);
push(&s,124);
push(&s,237);
ding(&s,&a);
c=length(&s);
printf("栈顶元素为:%d\n链栈长度为:%d\n",a,c);
while(!em(&s))
{
pop(&s,&d);
printf("%d ",d);
}
return 0;
}
代码实现效果图:
以上就是C语言实现链栈的方法了,虽然可能以后我们用别的语言时不用自己再编写这些代码,但是基本的原理我们还是要懂的。有错误或者问题可以留言,谢谢。