堆栈

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

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

操作

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

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

上面就是栈最核心的两个基本操作,可以在栈的可视化页面中直观理解这里的操作。[1]

栈的操作可视化图片

特点

堆栈的基本特点:

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

抽象定义

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

函数签名:

  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");
}

[3]

串列堆疊

存储结构

/* c2-2.h 线性表的单链表存储结构 */
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");
}

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

硬件堆栈

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

硬件支持

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

堆疊的應用

参考文献

  1. ^ 栈的可视化页面: 在线可视化演示栈的各种操作
  2. ^ Jones: "Systematic Software Development Using VDM"
  3. ^ 3.0 3.1 高一凡. 《数据结构》算法实现及解析 2004年10月第2版. 西安: 西安电子科技大学出版社. ISBN 9787560611761 (中文). 

参见

Read other articles:

2021 film score by Benjamin WallfischMortal Kombat: Original Motion Picture SoundtrackFilm score by Benjamin WallfischReleasedApril 16, 2021Recorded2020–2021StudioStudio 301, SydneyGenreFilm scoreLength79:40LabelWaterTower MusicBenjamin Wallfisch chronology The Invisible Man(2020) Mortal Kombat(2021) The Starling(2021) Mortal Kombat soundtrack chronology Mortal Kombat: Annihilation(1997) Mortal Kombat: Original Motion Picture Soundtrack(2021) Singles from Mortal Kombat: Original Mo...

 

Pour un article plus général, voir Décharge (déchet). Panneau à l'entrée d'une décharge de déchets dangereux (États-Unis, 1972). En France, une installation de stockage de déchets dangereux (ISDD) (ex- « décharge de classe 1 »[1]) est une installation classée pour la protection de l'environnement (ICPE) qui réceptionne des déchets dangereux en vue de les éliminer par enfouissement sur site. Définition Article connexe : Déchet dangereux. L'arrêté ministéri...

 

2013 Japanese Grand Prix Race 15 of 19 in the 2013 Formula One World Championship Suzuka CircuitRace detailsDate 13 October 2013Official name 2013 Formula 1 Japanese Grand Prix[1]Location Suzuka CircuitSuzuka, JapanCourse Permanent racing facilityCourse length 5.807 km (3.608 miles)Distance 53 laps, 307.471 km (191.054 miles)Weather Warm and sunnyAttendance 171,000[2]Pole positionDriver Mark Webber Red Bull-RenaultTime 1:30.915Fastest lapDriver Mark Webber Red Bull-RenaultTim...

Klungkung beralih ke halaman ini. Untuk kegunaan lain, lihat Klungkung (disambiguasi). Koordinat: 8°39′S 115°29′E / 8.650°S 115.483°E / -8.650; 115.483 Kabupaten KlungkungKabupatén KlùngkùngKabupatenTranskripsi bahasa daerah • Aksara Bali • Alfabet Baliᬓ᭄ᬮᬸᬂᬓᬸᬂKlùŋkùŋPuri Agung SemarapuraPantai Broken Nusa PenidaPantai Kelingking BenderaLambangJulukan: Gumi SerombotanMotto: Dharmaning ksatriya mahottama(Jawa K...

 

Belgian cyclist Dominique CornuPersonal informationFull nameDominique CornuBorn (1985-10-10) 10 October 1985 (age 38)Beveren, BelgiumHeight1.96 m (6 ft 5 in)Weight77 kg (170 lb)Team informationCurrent teamRetiredDisciplineRoadTrackRoleRiderRider typeTime triallistProfessional teams2005–2006Bodysol–Win for Life–Jong Vlaanderen2007–2008Predictor–Lotto2009Quick-Step2010Skil–Shimano2011–2013Topsport Vlaanderen–Mercator2014Sunweb–Napol...

 

Bahasa SumbaDituturkan diIndonesiaWilayah  Nusa Tenggara Timur EtnisSumbaPenutur3.240 (2020) Rumpun bahasaMelayu-Polinesia MP Tengah-TimurMP TengahBima-SumbaBahasa Sumba Kode bahasaISO 639-1-ISO 639-2-ISO 639-3sumQIDQ85804036  Portal Bahasa Sunting kotak info • L • B • PWBantuan penggunaan templat ini Cari artikel bahasa  Cari berdasarkan kode ISO 639 (Uji coba)  Kolom pencarian ini hanya didukung oleh beberapa antarmuka Halaman bahasa acak Pulau ...

American state election Not to be confused with 2018 United States House of Representatives elections in Michigan. 2018 Michigan House of Representatives election ← 2016 November 6, 2018 (2018-11-06) 2020 → All 110 seats in the Michigan House of Representatives56 seats needed for a majorityTurnout54.64%   Majority party Minority party   Leader Tom Leonard(term-limited) Sam Singh(term-limited) Party Republican Democratic Leader since January ...

 

International airport serving Costa del Sol, Malaga, Spain For the airport in Malaga, Colombia, see Jerónimo de Aguayo Airport. This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Málaga Airport – news · newspapers · books · scholar · JSTOR (October 2016) (Learn how and when to remove this message) Málaga Air...

 

Questa voce sull'argomento strade degli Stati Uniti d'America è solo un abbozzo. Contribuisci a migliorarla secondo le convenzioni di Wikipedia. U.S. Route 79LocalizzazioneStato Stati Uniti Stati federati Texas Louisiana Arkansas Tennessee Kentucky DatiClassificazioneAutostrada InizioRussellville FineRound Rock Lunghezza1 376 km Direzionenord-sud Data apertura1935 PercorsoPrincipali intersezioniFine a sud: Interstate 35 a Round Rock (TX) Interstate 45 a Bu...

Portrait of Johann Burchard Freystein Johann Burchard Freystein (18 April 1671 – 1 April 1718) was a German lawyer and hymn writer. Life Freystein was born in Weissenfels, the son of Samuel Adam Freystein, vice-chancellor of Duke August of Saxony, inspector of the Gymnasium of Weissenfels. Johann Burchard Freyenstein studied at the University of Leipzig in law, mathematics, philosophy and architecture. He spent some time in Berlin and Halle. In 1695 he achieved his doctorate in law at the U...

 

Si ce bandeau n'est plus pertinent, retirez-le. Cliquez ici pour en savoir plus. Cet article ne cite pas suffisamment ses sources (juin 2010). Si vous disposez d'ouvrages ou d'articles de référence ou si vous connaissez des sites web de qualité traitant du thème abordé ici, merci de compléter l'article en donnant les références utiles à sa vérifiabilité et en les liant à la section « Notes et références ». En pratique : Quelles sources sont attendues ? Comm...

 

Mahkamah Rayuan Persekutuan Malaysia (Melayu) محكمه رايوان فرسوكوتوان مليسيا (Jawi) Mahkamah Banding Federal Malaysia (Indonesia) Malaysian Federal Court of Appeal (Inggris) 马来西亚联邦上诉法院 (Mandarin) மலேசிய பெடரல் மேல்முறையீட்டு நீதிமன்றம் (Tamil)Mahkamah Rayuan MalaysiaDidirikan1994Negara MalaysiaLokasiIstana Kehakiman, PutrajayaCara penunjukkanDiangkat dan dilantik oleh Ra...

His EminenceRaffaele Monaco La VallettaSecretary of the Congregation of the Holy OfficeChurchRoman Catholic ChurchAppointed15 February 1884Term ended14 July 1896PredecessorLuigi BilioSuccessorLucido Maria ParocchiOther post(s)Cardinal Protector of the Pontifical Ecclesiastical Academy (1884–96)Major Penitentiary of the Apostolic Penitentiary (1884–96)Archpriest of the Basilica of Saint John Lateran (1885–96)Cardinal-Bishop of Ostia-Velletri (1889–96)Dean of the College of Cardinals (1...

 

Electronic test instrument that measures multiple signals from a circuit This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Logic analyzer – news · newspapers · books · scholar · JSTOR (December 2012) (Learn how and when to remove this message) Logic analyzer A logic analyzer is an electronic instrument that ca...

 

Ранжування країн за кількістю морських суден торговельного флоту з внутрішнім об'ємом більше 1 тис. реєстрових тонн, 2005 рік Проходження вантажних суден через шлюзи Мірафлорес Панамського каналу, 2000 рік Міст через Суецький канал, 2010 рік Супутниковий знімок Роттердамсько�...

Open-faced sandwich with ham and cheese Gerber sandwichGerber sandwichPlace of originUnited StatesRegion or stateSt. Louis, Missouri This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Gerber sandwich – news · newspapers · books · scholar · JSTOR (May 2011) (Learn how and when to remove this message) The Gerber ...

 

Cessy Mairie de Cessy. Blason Administration Pays France Région Auvergne-Rhône-Alpes Département Ain Arrondissement Gex Intercommunalité Pays de Gex Agglo Maire Mandat Christophe Bouvier 2020-2026 Code postal 01170 Code commune 01071 Démographie Gentilé Cessiens Populationmunicipale 5 307 hab. (2021 ) Densité 810 hab./km2 Géographie Coordonnées 46° 19′ 09″ nord, 6° 04′ 12″ est Altitude Min. 496 mMax. 593 m Superficie 6...

 

Line or vector perpendicular to a curve or a surface This article is about the normal to 3D surfaces. For the normal to 3D curves, see Frenet–Serret formulas. A polygon and its two normal vectors A normal to a surface at a point is the same as a normal to the tangent plane to the surface at the same point. In geometry, a normal is an object (e.g. a line, ray, or vector) that is perpendicular to a given object. For example, the normal line to a plane curve at a given point is the line perpen...

Judo competition Judo Men's 100 kg at the 2014 World Judo ChampionshipsVenueTraktor Ice ArenaLocationChelyabinsk, RussiaDate30 August 2014 Competitors44 from 38 nationsTotal prize money14,000$[1]Medalists  Lukáš Krpálek (1st title)   Czech Republic José Armenteros   Cuba Ivan Remarenco   United Arab Emirates Karl-Richard Frey   GermanyCompetition at external databasesLinksIJF • JudoInside&#...

 

Former administrative division of Yorkshire, England 54°20′17″N 1°25′44″W / 54.338°N 1.429°W / 54.338; -1.429 AllertonshireMap of the wapentakes of Yorkshire in 1832. Allertonshire, including its exclaves, is shown in pale green in the north-centre of the map.Statuswapentake, liberty Allertonshire or Allerton was a wapentake and liberty in the North Riding of Yorkshire, England.[1] Northallerton, current name of Allerton, was historically associated...