三.栈

栈的概念

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

栈的抽象数据类型

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

栈的顺序存储表示

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

栈的动态顺序存储表示

采用动态一维数组来存储栈,栈的大小可以根据需要增加。
栈底(bottom)固定不变,栈顶(top)随着进栈和退栈操作而变化;
top=bottom作为栈空的标记,每次top指向栈顶数组中的下一个存储位置;
结点进栈:首先将数据元素保存到栈顶(top所指的当前位置),然后执行top加1,使top指向栈顶的下一个存储位置;
结点出栈:首先执行top减1,使top指向栈顶元素的存储位置,然后将栈顶元素取出。

  • 栈的类型定义
#define STACK_SIZE 100 /* 栈初始向量大小*/
#define STACKINCREMENT 10 /* 存储空间分配增量*/
#typedef int ElemType;
typedef struct sqstack
{ ElemType *bottom;  /* 栈不存在时值为NULL*/
  ElemType *top;     /*栈顶指针*/
  int stacksize;     /*当前已分配空间,以元素为单位*/
}SqStack;
  • 栈的初始化
Status Init_Stack(void)
{  SqStack S;
   S.bottom = (ElemType*)malloc(STACK_SIZE*sizeof(ElemType));
   if(!S.bottom) return ERROR;
   S.top = S.bottom ;   /*栈空时栈顶和栈底指针相同*/
   S.stacksize = STACK_SIZE;
   return OK;
}
  • 元素进栈
Status Push(SaStack S,ElemType e)
{  if(S.top-S.bottom>=S.stacksize-1)
    {  S.bottom = (ElemType*)realloc((S.STACKINCREMENT+STACK_SIZE)*sizeof(ElemType));
    /*栈满,追加存储空间*/
    if(!S.bottom) return ERROR;
    S.top = S.bottom + S.stacksize;
    S.stacksize += STACKINCREMENT;
    }
    *S.top = e;S.top++;/*栈顶指针加1,e成为新的栈顶*/
    return OK;
}
  • 元素出栈
Status pop(SaStack S,ElemType *e)
/*弹出栈顶元素*/
{  	if(S.top==S.bottom)
	return ERROR;      /*栈空,返回失败标志*/
    S.top--;e = S.top;
    return OK;
}

栈的静态顺序存储表示

采用静态一维数组来存储栈,栈底固定不变,栈顶随着进栈和退栈操作变化。
栈底(bottom)固定不变,栈顶(top)随着进栈和退栈操作而变化;
top=0作为栈空的标记,每次top指向栈顶在数组中的存储位置;
结点进栈:首先执行top加1,使top指向新的栈顶位置,然后将数据元素保存到栈顶(top所指的当前位置);
结点出栈:首先把top指向的栈顶元素取出,然后执行top减1,使top指向新的栈顶位置。
若栈的数组有Maxsize个元素,则top=Maxsize-1时栈满。

  • 栈的类型定义
#define MAX_STACK_SIZE 100 /* 栈向量大小*/
#typedef int ElemType;
typedef struct sqstack
{ ElemType stack_array[MAX_STACK_SIZE ];
  int top;    
}SqStack;
  • 栈的初始化
SqStack Init_Stack(void)
{  SqStack S;
   S.bottom = S.top = 0;
   return(S);
}
  • 元素进栈
Status Push(SaStack S,ElemType e)
/*使数据元素e进栈成为新的栈顶*/
{  if(S.top==MAX_STACK_SIZE -1)
	   return ERROR;      /*栈满,返回错误标志*/
    S.top++;              /*栈顶指针加1*/
    S.stack_array[S.top]=e;/*e成为新的栈顶*/
    return OK;             /*进栈成功*/
    }
}
  • 元素出栈
Status pop(SaStack S,ElemType *e)
/*弹出栈顶元素*/
{  	if(S.top==0)
	return ERROR;      /*栈空,返回失败标志*/
    *e = stack_array[S.top];
    S.top--;
    return OK;
}

栈的链式存储表示

栈的链式表示

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

  • 链栈的类型定义
typedef struct Stack_Node
{ ElemType data;
  struct Stack_Node *next;
}Stack_Node;
  • 栈的初始化
Stack_Node *Init_Link_Stack(void)
{  Stack_Node *top;
   top=(Stack_Node *)malloc(sizeof(Stack_Node));
   top->next=null;
   return(top);
}
  • 元素进栈
Status Push(Stack_Node *top,ElemType e)
/*使数据元素e进栈成为新的栈顶*/
{  Stack_Node *p;
   p=(Stack_Node *)malloc(sizeof(Stack_Node));
   if(!p) return ERROR;
   /*申请新结点失败,返回错误标志*/
   p->data=e;
   p->next=top->next;
   top->next=p;     /*钩链*/
   return OK;
}
  • 元素出栈
Status pop(Stack_Node *top,ElemType *e)
/*弹出栈顶元素*/
{  	Stack_Node *p;
	ElemType e;
	if(top->next==NULL)
	return ERROR;      /*栈空,返回失败标志*/
    p=top->next;
    e=p->data;        /*取栈顶元素*/
    top->next=p->next;/*修改栈顶指针*/
    free(p);
    return OK;
}

posted on 2018-08-06 17:02  J_Xiong0117  阅读(171)  评论(1编辑  收藏  举报

导航