[数据结构]线性结构——栈

原创 2015年07月07日 20:46:44

栈和队列是两种特殊的线性表,它们的逻辑结构和线性表相同,只是其运算规则较线性表有更多的限制,故又称它们为运算受限的线性表。栈和队列被广泛应用于各种程序设计中。

栈的概念

  • (Stack):是限制在表的一端进行插入和删除操作的线性表。又称为后进先出LIFO(Last In First Out)或先进后出FILO(First In Last Out)线性表。
  • 栈顶(Top)允许进行插入、删除操作的一端,又称为表尾。用栈顶指针(top)来指示栈顶元素。
  • 栈底(Bottom)是固定端,又称为表头
  • 空栈:当表中没有元素时称为空栈。


栈的抽象数据类型定义

  1. ADT Stack  
  2. {  
  3.     数据对象:D={ ai|ai∈ElemSet, i=1,2,…,n,n≥0}  
  4.     数据关系:R={<ai-1,ai>|ai-1,ai∈D, i=2,3,…,n}  
  5.     基本操作:初始化、进栈、出栈、取栈顶元素等  
  6. }  

栈的顺序存储表示

栈的顺序存储结构简称为顺序栈,和线性表相类似,用一维数组来存储栈。根据数组是否可以根据需要增大,又可分为静态顺序栈动态顺序栈静态顺序栈实现简单,但不能根据需要增大栈的存储空间;动态顺序栈可以根据需要增大栈的存储空间,但实现稍为复杂。

栈的动态顺序存储表示

采用动态一维数组来存储栈。所谓动态,指的是栈的大小可以根据需要增加。

  • bottom表示栈底指针,栈底固定不变的;栈顶则随着进栈和退栈操作而变化。top(称为栈顶指针)指示当前栈顶位置。
  • top=bottom作为栈空的标记,每次top指向栈顶数组中的下一个存储位置。
  • 结点进栈:首先将数据元素保存到栈顶(top所指的当前位置),然后执行top1,使top指向栈顶的下一个存储位置;
  • 结点出栈:首先执行top1,使top指向栈顶元素的存储位置,然后将栈顶元素取出。

  1. //栈的类型定义  
  2. #define STACK_SIZE 100 /* 栈初始向量大小*/  
  3. #define STACKINCREMENT 10 /* 存储空间分配增量 */  
  4. typedef int ElemType ;  
  5. typedef struct sqstack  
  6. {   
  7.   ElemType *bottom; /* 栈不存在时值为NULL */  
  8.   ElemType *top; /* 栈顶指针 */  
  9.   int stacksize ; /* 当前已分配空间,以元素为单位 */  
  10. }SqStack ;  
  11.   
  12. //栈的初始化  
  13. int Init_Stack(void)  
  14. {   
  15.   SqStack S ;  
  16.   S.bottom=(ElemType*)malloc(STACK_SIZE *sizeof(ElemType));  
  17.   if (! S.bottom) return ERROR;  
  18.   S.top=S.bottom ; /* 栈空时栈顶和栈底指针相同 */  
  19.   S.stacksize=STACK_SIZE;  
  20.   return OK ;  
  21. }  
  22.   
  23. //压栈(元素进栈)  
  24. int push(SqStack S , ElemType e)  
  25. {  
  26.   if (S.top-S.bottom>=S.stacksize-1)  
  27.   {   
  28.     S.bottom=(ElemType *)realloc((S.STACKINCREMENT+STACK_SIZE)*sizeof(ElemType)); /* 栈满,追加存储空 间 */  
  29.     if (! S.bottom) return ERROR;  
  30.     S.top=S.bottom+S. stacksize ;  
  31.     S. stacksize+=STACKINCREMENT ;  
  32.   }  
  33.   *S.top=e;   
  34.   S.top++ ; /* 栈顶指针加1,e成为新的栈顶 */  
  35.   return OK;  
  36. }  
  37.   
  38. //弹栈(元素出栈)  
  39. int pop( SqStack S, ElemType *e )/*弹出栈顶元素*/  
  40. {  
  41.   if ( S.top== S.bottom )  
  42.     return ERROR ; /* 栈空,返回失败标志*/  
  43.   S.top-- ;  
  44.   e=*S. top ;  
  45.   return OK ;  
  46. }  

栈的静态顺序存储表示

采用静态一维数组来存储栈。

  • 栈底固定不变的;栈顶则随着进栈和退栈操作而变化,用一个整型变量top(称为栈顶指针)来指示当前栈顶位置。
  • top=0表示栈空的初始状态,每次top指向栈顶在数组中的存储位置。
  • 结点进栈:首先执行top1,使top指向新的栈顶位置,然后将数据元素保存到栈顶(top所指的当前位置)
  • 结点出栈:首先把top指向的栈顶元素取出,然后执行top1,使top指向新的栈顶位置。

若栈的数组有Maxsize个元素,则top=Maxsize-1时栈满。


  1. //基本操作的实现  
  2. //栈的类型定义  
  3. # define MAX_STACK_SIZE 100 /* 栈向量大小 */  
  4. typedef int ElemType ;  
  5. typedef struct sqstack  
  6. {   
  7.   ElemType stack_array[MAX_STACK_SIZE] ;  
  8.   int top;  
  9. }SqStack ;  
  10.   
  11. //栈的初始化  
  12. SqStack Init_Stack(void)  
  13. {   
  14.   SqStack S ;  
  15.   S.bottom=S.top=0 ;   
  16.   return(S) ;  
  17. }  
  18.   
  19. //压栈(元素进栈)  
  20. Status push(SqStack S , ElemType e)/* 使数据元素e进栈成为新的栈顶 */  
  21. {   
  22.   if (S.top==MAX_STACK_SIZE-1)  
  23.     return ERROR; /* 栈满,返回错误标志*/  
  24.   S.top++ ; /* 栈顶指针加1 */  
  25.   S.stack_array[S.top]=e ; /* e成为新的栈顶 */  
  26.   return OK; /* 压栈成功 */  
  27. }  
  28.   
  29. //弹栈(元素出栈)  
  30. Status pop( SqStack S, ElemType *e )/*弹出栈顶元素*/  
  31. {   
  32.   if ( S.top==0 )  
  33.     return ERROR ; /* 栈空,返回错误标志*/  
  34.   *e=S.stack_array[S.top] ;  
  35.   S.top-- ;  
  36.   return OK ;  
  37. }  

存储栈的链式表示

栈的链式存储结构称为链栈,是运算受限的单链表。其插入和删除操作只能在表头位置上进行。因此,链栈没有必要像单链表那样附加头结点,栈顶指针top就是链表的头指针。

  1. //链栈的结点类型说明如下:  
  2. typedef struct Stack_Node   
  3. {   
  4.     ElemType data ;  
  5.     struct Stack_Node *next ;   
  6. }Stack_Node ;  
  7.   
  8.   
  9. //链栈基本操作的实现--链栈基本操作的实现  
  10. //栈的初始化  
  11. Stack_Node *Init_Link_Stack(void)  
  12. {  
  13.     Stack_Node *top ;   
  14.     top=(Stack_Node*)malloc(sizeof(Stack_Node )) ;   
  15.     top->next=NULL ;  
  16.     return(top) ;  
  17. }  
  18.   
  19. //压栈(元素进栈)  
  20. Status push(Stack_Node *top , ElemType e)  
  21. {   
  22.     Stack_Node *p ;  
  23.     p=(Stack_Node *)malloc(sizeof(Stack_Node)) ;  
  24.     if (!p) return ERROR; /* 申请新结点失败,返回错误标志 */  
  25.     p->data=e ;   
  26.     p->next=top->next ;   
  27.     top->next=p ; /* 钩链 */   
  28.     return OK;  
  29. }  
  30.   
  31. //弹栈(元素出栈)  
  32. Status pop(Stack_Node *top , ElemType *e)/* 将栈顶元素出栈 */  
  33. {   
  34.     Stack_Node *p ;  
  35.     ElemType e ;  
  36.     if (top->next==NULL )  
  37.         return ERROR ; /* 栈空,返回错误标志 */  
  38.     p=top->next ;   
  39.     e=p->data ; /* 取栈顶元 素 */  
  40.     top->next=p->next ; /* 修改栈顶指针 */   
  41.     free(p) ;  
  42.     return OK;  


版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

线性结构—栈

线性结构之栈栈是一种只允许在一端进行插入和删除的线性表,它是一种操作受限的线性表,在表中只允许进行插入和删除的一端称为栈顶,另一端称为栈底顺序栈—栈的顺序存储结构基本操作如下: 初始化栈(建立栈空间,...

线性结构 栈

1.栈结构和操作定义 SeqStack.h //功能:定义栈结构体 #define MAXSIZE 10 typedef struct SeqStack{ DATA data[MAXSIZE +...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

线性结构——栈

栈是只能在表尾进行插入或删除操作的线性表,栈既然也是线性表,那么它也有顺序存储结构和链式存储结构两种表示方法,一般它被表示为顺序存储结构。 十进制正整数转换为二进制 /* * 十进制正整数转换为...

【数据结构】线性堆栈

栈也是一种很重要的数据结构,具备“先进后出”的特点。程序中的函数调用以及递归都涉及栈这一数据结构,熟悉栈有利于我们更好地理解函数的调用过程(主要是形参,局部变量以及函数的返回值)和递归算法的实现过程 ...

常用数据结构--线性结构

常用数据结构--线性结构

【数据结构】数据结构与算法(一)——线性结构

一、前言 二、内容介绍 三、对比记忆 四、小结

常用数据结构--线性结构

数据结构是计算机存储、组织数据的方式。常见的数据结构分类方式如下图: 常用的线性结构有:线性表,栈,队列,循环队列,数组。线性表中包括顺序表、链表等,其中,栈和队列只是属于逻辑上的概念,实际...

常用数据结构--线性结构

数据结构是计算机存储、组织数据的方式。常见的数据结构分类方式如下图: 常用的线性结构有:线性表,栈,队列,循环队列,数组。线性表中包括顺序表、链表等,其中,栈和队列只是属于逻辑上的概念,实际...

[数据结构]线性结构——队列

栈和队列是两种特殊的线性表,它们的逻辑结构和线性表相同,只是其运算规则较线性表有更多的限制,故又称它们为运算受限的线性表。栈和队列被广泛应用于各种程序设计中。 队列的基本概念 队列(Queue):...

线性表数据结构解读(三)栈结构Stack

在上一篇文章中,我们详细介绍了链式存储结构,并结合LinkedList源码进行了分析,相关文章大家可以点击这里回看我的博客:线性表数据结构解读(二)链式存储结构LinkedList栈的定义    栈是...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)