《C语言栈的图文解析和实现探讨.docx》由会员分享,可在线阅读,更多相关《C语言栈的图文解析和实现探讨.docx(5页珍藏版)》请在优知文库上搜索。
1、栈的介绍栈(stack),是一种线性存储结构,它有以下几个特点:栈中数据是按照”后进先出(LlFo,LastInFirstOut)”方式进出栈的。向栈中添加/删除数据时,只能从栈顶进行操作。栈通常包括的三种操作:push、peekpop。push向栈中添加元素。peek返回栈顶元素。pop一返回并删除栈顶元素的操作。1.栈的示意图栈中的数据依次是302010o2 .出栈一七栈底找底栈底I(1)出枝前zfI(2)出根动作Izb(3)出油后出栈前:栈顶元素是30。此时,栈中的元素依次是30-20-10。出栈后:30出栈之后,栈顶元素变成20。此时,栈中的元素依次是2010。3 .入栈I(1)入栈前
2、IC=JI(2)入极动作Il=(3)入枝后入栈前:栈顶元素是20。此时,栈中的元素依次是20-10。入栈后:40入栈之后,栈顶元素变成40o此时,栈中的元素依次是402010o栈的C实现1数组实现的栈,并且只能存储int数据实现代码:*IMfv*tlMI*Mt.l一MflaW*Wl*.(本图可以通过拖动边框的方式进行放大)运行结果:tmp=30tmp=20stacksize()=3402010结果说明:该示例中的栈,是通过“数组”来实现的!由于代码中己经给出了详细了注释,这里就不再对函数进行说明了。仅对主函数main的逻辑进行简单介绍:在主函数main中,先将”10,20,30”依次压入栈。此
3、时,栈的数据是:3020IOo接着通过pop()返回栈顶元素;P。Po操作并不会改变栈中的数据。此时,栈的数据依然是:302010。接着通过Peeko返回并删除栈顶元素。Peek操作之后,栈的数据是:2010o接着通过PUSh(40)将40压入栈中。PUSh(40)操作之后,栈的数据是:402010o2单向链表实现的栈,并且只能存储int数据实现代码:代码说明:”运行结果“以及主函数main的逻辑嘟和”C语言实现一”的一样。不同的是,该示例中的栈是通过单向链表实现的。3双向链表实现的栈,并且只能存储int数据实现代码:(1)双向链表的头文件(doubljlink.h)(2)双向链表的实现文件d
4、oubleink.c)(3)双向链表的测试程序(dlink_stack.c)代码说明:”运行结果”以及”主函数main的逻辑”都和前两个示例的一样。不同的是,该示例中的栈是通过双向链表实现的。4双向链表实现的栈,能存储任意类型的数据实现代码:(1)双向链表的头文件(doubleink.h)(2)双向链表的实现文件(doubleink.c)(3)双向链表的测试程序(dlink_stack.c)运行结果:id=40,name=danid=20,name=jodyid=10,name=sky结果说明:该示例中的栈是通过双向链表实现的,并且能存储任意类型的数据。示例中是以结构体类型的数据进行演示的,由
5、于代码中已经给出了详细的注释,这里就不再介绍了。C语言栈的表示与实现实例详解C语言三人行+2015-03-2700:06C语言的栈是指限定仅在表尾进行插入和删除操作的线性表。栈作为C语言中一种常用的数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另i端为栈底(bottom);栈底固定,而栈顶浮动
6、;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)o栈也称为后进先出表。在计算机系统中,栈则是一个具有以上属性的动态内存区域。程序可以将数据压入栈中,也可以将数据从栈顶弹出。在i386机器中,栈顶由称为esp的寄存器进行定位。压栈的操作使得栈顶的地址减小,弹出的操作使得栈顶的地址增大。栈在程序的运行中有着举足轻重的作用。最重要的是栈保存了一个函数调用时所需要的维护信息,这常常称之为堆栈帧或者活动记录。堆栈帧一般包含如下几方面的信息:(1)函数的返回地址和参数(2)临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量实例#defineSTACKJN
7、IT_SIZE10/*存储空间初始分配量*/defineSTACKINCREMENT2*存储空间分配增量*/typedefstructSqStackSElemTyPe*base;/*在栈构造之前和销毁之后,base的值为NULL*/SElemTyPe*top;/*栈顶指针*/Mtstacksize;/*前已分配的存储空间,以元素为单位*/SqStack;/*顺序栈*StatusInitStack(SqStack*S)/*构造一个空栈S*/(*S).base二(SEIemTyPe*)maHoc(STACKNrr_SIZE*SiZeOf(SEIemTyPe);if(!(*S).base)exit(
8、OVERFLOW);/*存储分再已失败*(*S).top=(*S).base;(*S).stacksize=STACKJNIT_SIZE;returnOK;StatusDestroyStack(SqStackS)/*销毁栈S,S不再存在*free(*S).base);(*S).base=NULL;(*S).top=NULL;(*S).Stacksize=O;retumOK;StatusClearStack(SqStack*S)/*把S置为空栈*(*S).top=(*S).base;retumOK;StatusStackEmpty(SqStackS)/*若栈S为空栈,则返回TRUE,否则返回FA
9、LSE*if(S.top=S.base)returnTRUE;elsereturnFALSE;intStackLength(SqStackS)/*返回S的元素个数,即栈的长度*/returnS.top-S.base;StatusGetTop(SqStackS,SElemType*e)/*若栈不空,则用e返回S的栈顶元素,并返回0K;否则返回ERRoR*/if(S.topS.base)*e=*(S.top-1);returnOK;elseretumERROR;StatusPush(SqStack*S,SElemTypee)/*插入元素e为新的栈顶元素*if(*S).top-(*S).base=(
10、*S).stacksize)/*栈满,追加存储空间*/(*S).base=(SelemType*)realloc(*S).base,(*S).stacksize+STACKINCREMENT)*sizeof(SElemType);if(!(*S).base)exit(OVERFLOW);/*存储分配失败*/(*S).top=(*S).base+(*S).stacksize;(*S).stacksize+=STACKINCREMENT;)*(*S).top)+=e;retumOK;StatUSPOP(SqStaCk*S,SElemType*e)*若栈不空,则删除S的栈顶元素,用e返回其值,并返回
11、0K;否则返回ERROR*if(*S).top=(*S).base)retumERROR;*e=*(*S).top;retumOK;StatusStackTraverse(SqStackS,Status(*visit)(SElemType)/*从栈底到栈顶依次对栈中每个元素调用函数VisitOo*一旦ViSito失败,则操作失败*while(S.topS.base)visit(*S.base+);printf(,n,)jretumOK;)#includeHcl.htypedefintSElemType;/*定义栈元素类型,此句要在c3-l.h的前面*/include,c3-1.h#includ
12、ebo3-1.CnStatusvisit(SElemTypec)printf(%d,c)returnOKJvoidmain()intj;SqStaCks;SElemTypee;if(InitStack(&s)=OK)for(j=l;j=12;j+)Push(&s,j);Printf(栈中元素依次为:)StackTraverse(s,visit);Pop(&s,&e);Printf(弹出的栈顶元素e=%dnu,e);Printf(栈空否:d(l:空0:否)n,StackEmpty);GetTOP(S,&e);Printf(栈顶元素e=%d栈的长度为dn,e,StackLength(三);ClearStack(&s);Printf(清空栈后,栈空否:%d(l:空0:否)n,StackEmpty(三);DestroyStack(&s);Printf(销毁栈s.top=%us.base=%us.stacksize=%dn,s.top,s.base,s.stacksize);