fbpx
维基百科

堆栈

堆疊(stack)又稱為堆叠,是计算机科學中的一種抽象資料型別,只允許在有序的線性資料集合的一端(稱為堆疊頂端,top)進行加入数据(push)和移除数据(pop)的運算。因而按照後進先出(LIFO, Last In First Out)的原理運作,堆疊常用一維数组連結串列來實現。常與另一種有序的線性資料集合佇列相提並論。

「堆栈」的各地常用別名
中国大陸堆栈、栈
港臺堆疊
堆疊的简单示意图

操作 编辑

堆疊使用兩種基本操作:推入(压栈,push)和彈出(弹栈,pop):

  • 推入:將資料放入堆疊頂端,堆疊頂端移到新放入的資料。
  • 彈出:將堆疊頂端資料移除,堆疊頂端移到移除後的下一筆資料。

特点 编辑

堆栈的基本特点:

  1. 先入后出,后入先出。
  2. 除头尾节点之外,每个元素有一个前驱,一个后继。

抽象定义 编辑

以下是堆栈的VDM(Vienna Development Method英语Vienna Development Method):[1]

函数签名:

 init: -> Stack push: N x Stack -> Stack top: Stack -> (N   ERROR) pop: Stack -> Stack isempty: Stack -> Boolean 

此处的N代表某个元素(如自然数),而 表示集合求并。

语义:

 top(init()) = ERROR top(push(i,s)) = i pop(init()) = init() pop(push(i, s)) = s isempty(init()) = true isempty(push(i, s)) = false 

软件堆栈 编辑

堆栈可以用数组链表两种方式实现,一般为一个堆栈预先分配一个大小固定且较合适的空间并非难事,所以较流行的做法是Stack结构下含一个数组。如果空间实在紧张,也可用链表实现,且去掉表头

这里的例程是以C語言实现的。

陣列堆疊 编辑

存储结构 编辑

/* c3-1.h 栈的顺序存储表示 */ #define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */ #define STACK_INCREMENT 2 /* 存储空间分配增量 */  typedef struct SqStack {  SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */  SElemType *top; /* 栈顶指针 */  int stacksize; /* 当前已分配的存储空间,以元素为单位 */ }SqStack; /* 顺序栈 */ 

基本操作 编辑

/* bo3-1.c 顺序栈(存储结构由c3-1.h定义)的基本操作(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"); } 

[2]

串列堆疊 编辑

存储结构 编辑

/* c2-2.h 线性表的单链表存储结构 */ typedef struct LNode {  ElemType data;  struct LNode *next; }; typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */ 

基本操作 编辑

/* bo3-5.c 链栈(存储结构由c2-2.h定义)的基本操作(4个) */ /* 部分基本操作是由bo2-8.cpp中的函数改名得来 */ /* 另一部分基本操作是由调用bo2-8.cpp中的函数(取特例)得来 */ typedef SElemType ElemType; /* 栈结点类型和链表结点类型一致 */ #include"c2-2.h" /* 单链表存储结构 */ typedef LinkList LinkStack; /* LinkStack是指向栈结点的指针类型 */ #define InitStack InitList /* InitStack()与InitList()作用相同,下同 */ #define DestroyStack DestroyList #define ClearStack ClearList #define StackEmpty ListEmpty #define StackLength ListLength #include"bo2-8.c" /* 无头结点单链表的基本操作 */  Status GetTop(LinkStack S,SElemType *e) { /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */  return GetElem(S,1,e); }  Status Push(LinkStack *S,SElemType e) { /* 插入元素e为新的栈顶元素 */  return ListInsert(S,1,e); }  Status Pop(LinkStack *S,SElemType *e) { /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */  return ListDelete(S,1,e); }  void StackTraverse(LinkStack S,void(*visit)(SElemType)) { /* 从栈底到栈顶依次对栈中每个元素调用函数visit() */  LinkStack temp,p=S; /* p指向栈顶元素 */  InitStack(&temp); /* 初始化临时栈temp */  while(p)  {  Push(&temp,p->data); /* 由S栈顶到栈底,依次将栈元素入栈到temp栈 */  p=p->next;  }  ListTraverse(temp,visit); /* 遍历temp线性表 */ } 

链表基本操作 编辑

/* bo2-8.c 不带头结点的单链表(存储结构由c2-2.h定义)的部分基本操作(9个) */ #define DestroyList ClearList /* DestroyList()和ClearList()的操作是一样的 */ void InitList(LinkList *L) { /* 操作结果:构造一个空的线性表L */  *L=NULL; /* 指针为空 */ }  void ClearList(LinkList *L) { /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */  LinkList p;  while(*L) /* L不空 */  {  p=*L; /* p指向首元结点 */  *L=(*L)->next; /* L指向第2个结点(新首元结点) */  free(p); /* 释放首元结点 */  } }  Status ListEmpty(LinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */  if(L)  return FALSE;  else  return TRUE; }  int ListLength(LinkList L) { /* 初始条件:线性表L已存在。操作结果:返回L中数据元素个数 */  int i=0;  LinkList p=L;  while(p) /* p指向结点(没到表尾) */  {  p=p->next; /* p指向下一个结点 */  i++;  }  return i; }  Status GetElem(LinkList L,int i,ElemType *e) { /* L为不带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */  int j=1;  LinkList p=L;  if(i<1) /* i值不合法 */  return ERROR;  while(j<i&&p) /* 没到第i个元素,也没到表尾 */  {  j++;  p=p->next;  }  if(j==i) /* 存在第i个元素 */  {  *e=p->data;  return OK;  }  else  return ERROR; }  int LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType)) { /* 初始条件:线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0) */  /* 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。 */  /* 若这样的数据元素不存在,则返回值为0 */  int i=0;  LinkList p=L;  while(p)  {  i++;  if(compare(p->data,e)) /* 找到这样的数据元素 */  return i;  p=p->next;  }  return 0; }  Status ListInsert(LinkList *L,int i,ElemType e) { /* 在不带头结点的单链线性表L中第i个位置之前插入元素e */  int j=1;  LinkList p=*L,s;  if(i<1) /* i值不合法 */  return ERROR;  s=(LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */  s->data=e; /* 给s的data域赋值 */  if(i==1) /* 插在表头 */  {  s->next=*L;  *L=s; /* 改变L */  }  else  { /* 插在表的其余处 */  while(p&&j<i-1) /* 寻找第i-1个结点 */  {  p=p->next;  j++;  }  if(!p) /* i大于表长+1 */  return ERROR;  s->next=p->next;  p->next=s;  }  return OK; }  Status ListDelete(LinkList *L,int i,ElemType *e) { /* 在不带头结点的单链线性表L中,删除第i个元素,并由e返回其值 */  int j=1;  LinkList p=*L,q;  if(i==1) /* 删除第1个结点 */  {  *L=p->next; /* L由第2个结点开始 */  *e=p->data;  free(p); /* 删除并释放第1个结点 */  }  else  {  while(p->next&&j<i-1) /* 寻找第i个结点,并令p指向其前驱 */  {  p=p->next;  j++;  }  if(!p->next||j>i-1) /* 删除位置不合理 */  return ERROR;  q=p->next; /* 删除并释放结点 */  p->next=q->next;  *e=q->data;  free(q);  }  return OK; }  void ListTraverse(LinkList L,void(*vi)(ElemType)) { /* 初始条件:线性表L已存在。操作结果:依次对L的每个数据元素调用函数vi() */  LinkList p=L;  while(p)  {  vi(p->data);  p=p->next;  }  printf("\n"); } 

[2] 堆棧有時候也常用來指代堆棧段

硬件堆栈 编辑

架构层次上的堆栈通常被用以申请和访问内存。

硬件支持 编辑

大多数CPU都有用作堆栈指针的寄存器。

堆疊的應用 编辑

参考文献 编辑

  1. ^ Jones: "Systematic Software Development Using VDM"
  2. ^ 2.0 2.1 高一凡. 《数据结构》算法实现及解析 2004年10月第2版. 西安: 西安电子科技大学出版社. ISBN 9787560611761 (中文). 

参见 编辑

堆栈, 此條目需要补充更多来源, 2020年5月24日, 请协助補充多方面可靠来源以改善这篇条目, 无法查证的内容可能會因為异议提出而被移除, 致使用者, 请搜索一下条目的标题, 来源搜索, 网页, 新闻, 书籍, 学术, 图像, 以检查网络上是否存在该主题的更多可靠来源, 判定指引, 堆疊, stack, 又稱為棧或堆叠, 是计算机科學中的一種抽象資料型別, 只允許在有序的線性資料集合的一端, 稱為堆疊頂端, 進行加入数据, push, 和移除数据, 的運算, 因而按照後進先出, lifo, last, firs. 此條目需要补充更多来源 2020年5月24日 请协助補充多方面可靠来源以改善这篇条目 无法查证的内容可能會因為异议提出而被移除 致使用者 请搜索一下条目的标题 来源搜索 堆栈 网页 新闻 书籍 学术 图像 以检查网络上是否存在该主题的更多可靠来源 判定指引 堆疊 stack 又稱為棧或堆叠 是计算机科學中的一種抽象資料型別 只允許在有序的線性資料集合的一端 稱為堆疊頂端 top 進行加入数据 push 和移除数据 pop 的運算 因而按照後進先出 LIFO Last In First Out 的原理運作 堆疊常用一維数组或連結串列來實現 常與另一種有序的線性資料集合佇列相提並論 堆栈 的各地常用別名中国大陸堆栈 栈港臺堆疊堆疊的简单示意图 目录 1 操作 2 特点 3 抽象定义 4 软件堆栈 4 1 陣列堆疊 4 1 1 存储结构 4 1 2 基本操作 4 2 串列堆疊 4 2 1 存储结构 4 2 2 基本操作 4 2 3 链表基本操作 5 硬件堆栈 5 1 硬件支持 6 堆疊的應用 7 参考文献 8 参见操作 编辑堆疊使用兩種基本操作 推入 压栈 push 和彈出 弹栈 pop 推入 將資料放入堆疊頂端 堆疊頂端移到新放入的資料 彈出 將堆疊頂端資料移除 堆疊頂端移到移除後的下一筆資料 特点 编辑堆栈的基本特点 先入后出 后入先出 除头尾节点之外 每个元素有一个前驱 一个后继 抽象定义 编辑以下是堆栈的VDM Vienna Development Method 英语 Vienna Development Method 1 函数签名 init gt Stack push N x Stack gt Stack top Stack gt N textstyle cup nbsp ERROR pop Stack gt Stack isempty Stack gt Boolean 此处的N代表某个元素 如自然数 而 textstyle cup nbsp 表示集合求并 语义 top init ERROR top push i s i pop init init pop push i s s isempty init true isempty push i s false软件堆栈 编辑堆栈可以用数组和链表两种方式实现 一般为一个堆栈预先分配一个大小固定且较合适的空间并非难事 所以较流行的做法是Stack结构下含一个数组 如果空间实在紧张 也可用链表实现 且去掉表头 这里的例程是以C語言实现的 陣列堆疊 编辑 存储结构 编辑 c3 1 h 栈的顺序存储表示 define STACK INIT SIZE 10 存储空间初始分配量 define STACK INCREMENT 2 存储空间分配增量 typedef struct SqStack SElemType base 在栈构造之前和销毁之后 base的值为NULL SElemType top 栈顶指针 int stacksize 当前已分配的存储空间 以元素为单位 SqStack 顺序栈 基本操作 编辑 bo3 1 c 顺序栈 存储结构由c3 1 h定义 的基本操作 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 gt S base e S top 1 return OK else return ERROR void Push SqStack S SElemType e 插入元素e为新的栈顶元素 if S top S base gt 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 gt S base visit S base printf n 2 串列堆疊 编辑 存储结构 编辑 c2 2 h 线性表的单链表存储结构 typedef struct LNode ElemType data struct LNode next typedef struct LNode LinkList 另一种定义LinkList的方法 基本操作 编辑 bo3 5 c 链栈 存储结构由c2 2 h定义 的基本操作 4个 部分基本操作是由bo2 8 cpp中的函数改名得来 另一部分基本操作是由调用bo2 8 cpp中的函数 取特例 得来 typedef SElemType ElemType 栈结点类型和链表结点类型一致 include c2 2 h 单链表存储结构 typedef LinkList LinkStack LinkStack是指向栈结点的指针类型 define InitStack InitList InitStack 与InitList 作用相同 下同 define DestroyStack DestroyList define ClearStack ClearList define StackEmpty ListEmpty define StackLength ListLength include bo2 8 c 无头结点单链表的基本操作 Status GetTop LinkStack S SElemType e 若栈不空 则用e返回S的栈顶元素 并返回OK 否则返回ERROR return GetElem S 1 e Status Push LinkStack S SElemType e 插入元素e为新的栈顶元素 return ListInsert S 1 e Status Pop LinkStack S SElemType e 若栈不空 则删除S的栈顶元素 用e返回其值 并返回OK 否则返回ERROR return ListDelete S 1 e void StackTraverse LinkStack S void visit SElemType 从栈底到栈顶依次对栈中每个元素调用函数visit LinkStack temp p S p指向栈顶元素 InitStack amp temp 初始化临时栈temp while p Push amp temp p gt data 由S栈顶到栈底 依次将栈元素入栈到temp栈 p p gt next ListTraverse temp visit 遍历temp线性表 链表基本操作 编辑 bo2 8 c 不带头结点的单链表 存储结构由c2 2 h定义 的部分基本操作 9个 define DestroyList ClearList DestroyList 和ClearList 的操作是一样的 void InitList LinkList L 操作结果 构造一个空的线性表L L NULL 指针为空 void ClearList LinkList L 初始条件 线性表L已存在 操作结果 将L重置为空表 LinkList p while L L不空 p L p指向首元结点 L L gt next L指向第2个结点 新首元结点 free p 释放首元结点 Status ListEmpty LinkList L 初始条件 线性表L已存在 操作结果 若L为空表 则返回TRUE 否则返回FALSE if L return FALSE else return TRUE int ListLength LinkList L 初始条件 线性表L已存在 操作结果 返回L中数据元素个数 int i 0 LinkList p L while p p指向结点 没到表尾 p p gt next p指向下一个结点 i return i Status GetElem LinkList L int i ElemType e L为不带头结点的单链表的头指针 当第i个元素存在时 其值赋给e并返回OK 否则返回ERROR int j 1 LinkList p L if i lt 1 i值不合法 return ERROR while j lt i amp amp p 没到第i个元素 也没到表尾 j p p gt next if j i 存在第i个元素 e p gt data return OK else return ERROR int LocateElem LinkList L ElemType e Status compare ElemType ElemType 初始条件 线性表L已存在 compare 是数据元素判定函数 满足为1 否则为0 操作结果 返回L中第1个与e满足关系compare 的数据元素的位序 若这样的数据元素不存在 则返回值为0 int i 0 LinkList p L while p i if compare p gt data e 找到这样的数据元素 return i p p gt next return 0 Status ListInsert LinkList L int i ElemType e 在不带头结点的单链线性表L中第i个位置之前插入元素e int j 1 LinkList p L s if i lt 1 i值不合法 return ERROR s LinkList malloc sizeof struct LNode 生成新结点 s gt data e 给s的data域赋值 if i 1 插在表头 s gt next L L s 改变L else 插在表的其余处 while p amp amp j lt i 1 寻找第i 1个结点 p p gt next j if p i大于表长 1 return ERROR s gt next p gt next p gt next s return OK Status ListDelete LinkList L int i ElemType e 在不带头结点的单链线性表L中 删除第i个元素 并由e返回其值 int j 1 LinkList p L q if i 1 删除第1个结点 L p gt next L由第2个结点开始 e p gt data free p 删除并释放第1个结点 else while p gt next amp amp j lt i 1 寻找第i个结点 并令p指向其前驱 p p gt next j if p gt next j gt i 1 删除位置不合理 return ERROR q p gt next 删除并释放结点 p gt next q gt next e q gt data free q return OK void ListTraverse LinkList L void vi ElemType 初始条件 线性表L已存在 操作结果 依次对L的每个数据元素调用函数vi LinkList p L while p vi p gt data p p gt next printf n 2 堆棧有時候也常用來指代堆棧段 硬件堆栈 编辑架构层次上的堆栈通常被用以申请和访问内存 硬件支持 编辑 大多数CPU都有用作堆栈指针的寄存器 堆疊的應用 编辑回溯 递归 深度優先搜尋参考文献 编辑 Jones Systematic Software Development Using VDM 2 0 2 1 高一凡 数据结构 算法实现及解析 2004年10月第2版 西安 西安电子科技大学出版社 ISBN 9787560611761 中文 参见 编辑 nbsp 计算机科学主题 連結串列 佇列 取自 https zh wikipedia org w index php title 堆栈 amp oldid 74879551, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。