重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
链栈其实也是链表的一种形式,头指针始终指向表的第一个结点(或是头结点),而栈顶指针则始终指向栈顶,创建链表时有一般有两种方法:一种是头插法,一种是尾插法。链栈也是一样的,假设创建的栈没有头结点即第一个结点就开始存储数据,按头插法建栈时,头指针就是栈顶指针,二者没有区别;按尾插法建栈时,则头指针就不是栈顶指针了,这时在建栈时就要再定义一个尾指针,让它始终指向栈的最后一个元素(即最后进栈的元素),这样该尾指针就是栈顶指针了。
创新互联成都企业网站建设服务,提供成都网站设计、成都做网站网站开发,网站定制,建网站,网站搭建,网站设计,响应式网站,网页设计师打造企业风格网站,提供周到的售前咨询和贴心的售后服务。欢迎咨询做网站需要多少钱:028-86922220
存储结构不同:
链栈动态分配内存存储数据,不浪费内存,存储的数据不连续。
顺序栈使用固定大小数组保存数据,数据量小时浪费内存,过多时出问题,存储数据连续。
它们的具体区别如下:
顺序栈的实现在于使用了数组这个基本数据结构,数组中的元素在内存中的存储位置是连续的,且编译器要求我们在编译期就要确定数组的大小,这样对内存的使用效率并不高,一来无法避免因数组空间用光而引起的溢出问题。在系统将内存分配给数组后,则这些内存对于其他任务就不可用。而对于链栈而言,使用了链表来实现栈,链表中的元素存储在不连续的地址,由于是动态申请内存,所以我们可以以非常小的内存空间开始,另外当某个项不使用时也可将内存返还给系统。
1.时间性能比较顺序栈和链栈基本操作的算法,时间复杂度均为O(1)。
2)空间性能比较初始时顺序栈必须确定一个固定的长度,所以有存储元素个数的限制和空间浪费的问题。
链栈无栈满问题,只有当内存没有可用空间时才会出现栈满,但是每个元素都需要一个指针域,从而产生了结构性开销。
一般结论:当栈在使用过程中元素个数变化较大时,用链栈比较好,反之,应该采用顺序栈。
若是栈中元素的数目变化范围较大或不清楚栈元素的数目,就应该考虑使用链式存储结构。人们将用链式存储结构表示的栈称作“链栈”。链栈通常用一个无头结点的单链表表示。由于栈的插入、删除操作只能在一端进行,而对于单链表来说,在首端插入、删除结点要比在尾端进行相对容易一些,所以将单链表的首端作为栈的顶端,即将单链表的头指针作为栈顶指针。链栈如图1所示。
图1链栈的存储示意
#includestdio.h
#includemalloc.h
typedef int ElemType;
typedef struct linknode
{
ElemType data; //数据域
struct linknode *next; //指针域
}LiStack; //链栈类型的定义
//初始化栈
void InitStack(LiStack *s)
{
s=(LiStack *)malloc(sizeof(LiStack));
s-next=NULL;
}
//销毁栈
void ClearStack(LiStack *s)
{
LiStack *p=s-next;
while(p!=NULL)
{
free(s);
s=p;
p=p-next;
}
free(s); //
}
//求战的长度
void StackLength(LiStack *s)
{
int i=0;
LiStack *p;
p=s-next;
while(p!=NULL)
{
i++;
p=p-next;
}
printf("目前此栈的长度为: %d\n",i);
}
//判断栈是否为空栈
void StackEmpty(LiStack *s)
{
if(s-next==NULL)
printf("目前此栈是空栈n");
else
printf("目前此栈不是空栈\n");
}
//进栈
void Push(LiStack *s,ElemType e)
{
LiStack *p;
p=(LiStack *)malloc(sizeof(LiStack));
p-data=e;
p-next=s-next; //插入*p结点作为第一个数据结点
s-next=p;
}
//出栈
void Pop(LiStack *s,ElemType e)
{
LiStack *p;
if(s-next==NULL)
{
printf("目前此栈是空栈,此次出栈失败了!\n");
}
else
{
p=s-next; //p指向第一个数据结点
e=p-data;
s-next=p-next;
free(p);
printf("此次出栈成功,出栈元素是:%d\n",e);
}
}
//取栈顶元素
void GetTop(LiStack *s,ElemType e)
{
LiStack *p;
p=s-next;
if(p==NULL)
printf("目前此栈是空栈,此次取栈顶元素失败了\n");
else
{
e=p-data;
printf("此次取栈顶的元素是:%d\n",e);
}
}
//显示栈中元素
void DispStack(LiStack *s)
{
LiStack *p;
p=s-next;
if(p==NULL)
printf("此栈目前是空栈\n");
else
{
printf("下面输出链栈里的各个元素:\n");
while(p!=NULL)
{
printf("%d ",p-data);
p=p-next;
}
printf("\n");
}
}
void main()
{
LiStack *s;
int e;
InitStack(s);
printf("请输入一个进栈元素:\n");
scanf("%d",e);
while(e!=0)
{
Push(s,e);
DispStack(s);
StackLength(s);
printf("请输入一个进栈元素:\n");
scanf("%d",e);
}
StackEmpty(s);
GetTop(s,e);
int i;
printf("如果你想出栈元素,请按1\n");
scanf("%d",i);
while(i==1)
{
Pop(s,e);
DispStack(s);
StackLength(s);
printf("如果你想继续出栈元素,请按1\n");
scanf("%d",i);
}
printf("链栈的基本运算,到此操作完毕了哦!\n");
}
顺序栈和链栈区别如下:
1。存储结构不同,顺序栈是静态分配的,而链栈则是动态分配的,链栈可以将很多零碎的空间利用起来,容量可变,节省空间,顺序栈则固定内存空间,容量不变。
2。使用方面,顺序栈查询速度快,链栈添加删除数据更快。