首页 | 主题 | 图库 | 问答 | 文摘 | 原创 | 百科

历史 | 地理 | 人物 | 艺术 | 体育 | 科学 | 音乐 | 电影 | 信息技术 | 世界遗产

 开放、中立,源自维基百科

个人工具


堆栈

维库,知识与思想的自由文库

跳转到: 导航, 搜索


堆栈又稱堆疊(stack)在计算机科学中,是一种特殊的链表形式的数据结构,它的特殊之处在于只能允许在链表的一端(称为栈顶,英文为top)进行添加和删除操作。另外堆栈数据结构的实现也可以通过数组来完成。


由于堆栈数据结构只允许在一端进行操作,因而按照先进后出(LIFO-Last In First Out)的原理工作。

堆栈数据结构支持两种基本操作:压栈(push)和弹栈(pop):

  1. 压栈(入栈):将对象或者数据压入栈中,更新栈顶指针,使其指向最后入栈的对象或数据。
  2. 弹栈(出栈):返回栈顶指向的对象或数据,并从栈中删除该对象或数据,更新栈顶。

[编辑] 顺序栈

/*栈的顺序存储表示 */
#define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */
#define STACK_INCREMENT 2 /* 存储空间分配增量 */
typedef struct SqStack
{
  SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */
  SElemType *top; /* 栈顶指针 */
  int stacksize; /* 当前已分配的存储空间,以元素为单位 */
}SqStack; /* 顺序栈 */
/*顺序栈的基本操作(9个) */
void InitStack(SqStack *S)
{ /* 构造一个空栈S */
  (*S).base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
  if(!(*S).base)
    exit(OVERFLOW); /* 存储分配失败 */
  (*S).top=(*S).base;
  (*S).stacksize=STACK_INIT_SIZE;
}
void DestroyStack(SqStack *S)
{ /* 销毁栈S,S不再存在 */
  free((*S).base);
  (*S).base=NULL;
  (*S).top=NULL;
  (*S).stacksize=0;
}
void ClearStack(SqStack *S)
{ /* 把S置为空栈 */
  (*S).top=(*S).base;
}
Status StackEmpty(SqStack S)
{ /* 若栈S为空栈,则返回TRUE,否则返回FALSE */
  if(S.top==S.base)
    return TRUE;
  else
    return FALSE;
}
int StackLength(SqStack S)
{ /* 返回S的元素个数,即栈的长度 */
  return S.top-S.base;
}
Status GetTop(SqStack S,SElemType *e)
{ /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
  if(S.top>S.base)
  {
    *e=*(S.top-1);
    return OK;
  }
  else
    return ERROR;
}
void Push(SqStack *S,SElemType e)
{ /* 插入元素e为新的栈顶元素 */
  if((*S).top-(*S).base>=(*S).stacksize) /* 栈满,追加存储空间 */
  {
    (*S).base=(SElemType *)realloc((*S).base,((*S).stacksize+STACK_INCREMENT)*sizeof(SElemType));
    if(!(*S).base)
      exit(OVERFLOW); /* 存储分配失败 */
    (*S).top=(*S).base+(*S).stacksize;
    (*S).stacksize+=STACK_INCREMENT;
  }
  *((*S).top)++=e;
}
Status Pop(SqStack *S,SElemType *e)
{ /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
  if((*S).top==(*S).base)
    return ERROR;
  *e=*--(*S).top;
  return OK;
}
void StackTraverse(SqStack S,void(*visit)(SElemType))
{ /* 从栈底到栈顶依次对栈中每个元素调用函数visit() */
  while(S.top>S.base)
    visit(*S.base++);
  printf("\n");

[编辑] 链栈

/*链栈的结构定义*/
typedef struct { 
  SLink top;    // 栈顶指针 
  int length;   // 栈中元素个数
}Stack;
void InitStack ( Stack &S )
{ 
  // 构造一个空栈 S
  S.top = NULL;   // 设栈顶指针的初值为"空" 
  S.length = 0;   // 空栈中元素个数为0
} // InitStack
/*能否将链栈中的指针方向反过来,从栈底到栈顶?  
 不行,如果反过来的话,删除栈顶元素时,为修改其前驱指针,需要从栈底一直找到栈顶。*/ 

void Push ( Stack &S, ElemType e )
{
  // 在栈顶之上插入元素 e 为新的栈顶元素
  p = new LNode;   // 建新的结点
  if(!p) exit(1);  // 存储分配失败
  p -> data = e;
  p -> next = S.top; // 链接到原来的栈顶
  S.top = p;     // 移动栈顶指针
  ++S.length;     // 栈的长度增1
} // Push
/*在链栈的类型定义中设立"栈中元素个数"的成员是为了便于求得栈的长度。*/
bool Pop ( Stack &S, SElemType &e )
{ 
  // 若栈不空,则删除S的栈顶元素,用 e 返回其值,
  // 并返回 TRUE;否则返回 FALSE
  if ( !S.top )
    return FALSE; 
    else 
    {
      e = S.top -> data;   // 返回栈顶元素 
      q = S.top; 
      S.top = S.top -> next; // 修改栈顶指针 
      --S.length;       // 栈的长度减1 
      delete q;       // 释放被删除的结点空间
      return TRUE;
    }
} // Pop  

堆栈有时候也常用来指代堆栈段

[编辑] 参见

其它语言
AD Links