數據結構之棧的實現

百度百科:棧(stack)又名堆棧,它是一種運算受限的線性表。限定僅在表尾進行插入和刪除操作的線性表。這一端被稱爲棧頂,相對地,把另一端稱爲棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成爲新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成爲新的棧頂元素。


前言:以下代碼僅供參考。若你也在學數據結構,那麼你可以參考我的學習方法:
1.理解對應數據結構
2.準備紙和筆,在紙上把對應操作的實現,用圖畫的形式推演一篇。
3.打開IDE,依據第二步的思路,編寫代碼。
4.測試代碼
5.對照書本實現。

棧的抽象數據類型

來源《大話數據結構》

ADT Stack()
Data
	同線性表。元素具有相同的類型,相鄰的元素具有前驅和後驅關係。

Operation:
	InitStack(*S);初始化操作,建立一個空棧
	DestroyStack(*S);若棧存在,銷燬
	ClearStack(*S);若存在,清空
	StackEmpty(*S);若空棧返回true,否則false
	GetTop(*S, *e);若存在,獲得棧頂元素
	Push(*S, e);若存在,入棧
	Pop(*S, *e);若存在,出棧
	StackLength(S);若存在,返回元素個數.

EndADT

棧的順序存儲結構實現——C語言描述

棧的定義:

typedef struct 
{
	int data[MAXSIZE];
	int top;
}Stack;

Operation: 初始化棧空間

//初始化棧空間
bool InitStack(Stack* s)
{
	s->data[MAXSIZE - 1] = { 0 };
	s->top = -1;
	
	return OK;
}

Operation: 入棧

//push,入棧操作
int Push(Stack* s, int e)
{
	//判斷棧空間是否滿了
	if (s->top == MAXSIZE - 1 || !s)
		return ERR;

	s->data[++s->top] = e;

	return OK;
}

Operation: 彈棧

//pop,彈棧操作
int Pop(Stack* s, int* e)
{
	//判斷棧是否爲空,或不存在
	if (s->top == -1 || !s)
		return ERR;

	*e = s->data[s->top--];

	return OK;
}

Operation: 銷燬

//若棧存在,銷燬
int DestroyStack(Stack* s)
{
	if (!s)
		return ERR;

	free(s);
	s = NULL;

	return OK;
}

Operation: 清空棧

//清空棧
bool ClearStack(Stack* s)
{
	if (!s || s->top == -1)
		return ERR;

	s->data[MAXSIZE - 1] = { 0 };
	s->top = -1;

	return OK;
}

Operation: 獲取棧頂元素

//獲取棧頂元素
int GetTopElem(Stack* s, int *e)
{
	if (!s || s->top == -1)
		return ERR;

	*e = s->data[s->top];

	return OK;
}

Operation: 返回棧的元素個數

//返回棧的元素個數
int StackLength(Stack* s, int* length)
{
	if (!s)
		return ERR;
	
	*length = s->top + 1;

	return OK;
}

順序存儲結構的雙棧共享空間

棧的長度是固化的,是定義棧時就必須指定的。這勢必造成一定棧空間得不到有效利用。例如如果一個棧能夠容納4K,而我們經常用的只是前2K,這就造成了後2K的利用率低下,而有效棧空間的內存是及其有限的且十分重要的,比如內核棧空間。因此棧空間的利用率從棧底往後延伸利用率不斷降低。
爲了解決這個問題也是爲了提高棧空間的利用率,因此出現了同一個棧空間兩個棧頂指針,分居棧空間兩端。

棧的定義:

typedef struct
{
	int data[MAXSIZE];
	int topLeft;
	int topRight;
}Stack;

Operation: 初始化棧空間

bool InitStack(Stack* s)
{
	if (!s)
		return ERR;

	s->data[MAXSIZE - 1] = { 0 };
	s->topLeft = -1;
	s->topLeft = MAXSIZE - 1;

	return OK;
}

Operation: 入棧

int Push(Stack* s, int e, int StackNum)
{
	//判斷棧空間是否滿了,或爲空
	if (s->topLeft + 1 == s->topRight || !s)
		return ERR;

	if (StackNum == 1)
	{
		s->data[++s->topLeft] = e;
	}
	else if (StackNum == 2)
	{
		s->data[--s->topRight] = e;
	}
	else
	{
		return ERR;
	}
	

	return OK;
}

Operation: 彈棧

int Pop(Stack* s, int* e, int StackNum)
{
	//判斷棧是否爲不存在
	if (!s)
		return ERR;

	if (StackNum == 1 && s->topLeft != -1)
	{
		*e = s->data[s->topLeft--];
	}
	else if (StackNum == 2 && s->topRight != MAXSIZE)
	{
		*e = s->data[s->topRight++];
	}
	else
	{
		return ERR;
	}
	

	return OK;
}

Operation: 銷燬

//若棧存在,銷燬
int DestroyStack(Stack* s)
{
	if (!s)
		return ERR;

	free(s);
	s = NULL;

	return OK;
}

Operation: 清空棧

//清空棧
bool ClearStack(Stack* s)
{
	if (!s)
		return ERR;

	s->data[MAXSIZE - 1] = { 0 };
	s->topLeft = -1;
	s->topRight = MAXSIZE;

	return OK;
}

Operation: 獲取棧頂元素

int GetTopElem(Stack* s, int* e, int StackNum)
{
	if (!s)
		return ERR;

	if (StackNum == 1 && s->topLeft != -1)
	{
		*e = s->data[s->topLeft];
	}
	else if (StackNum == 2 && s->topRight != MAXSIZE)
	{
		*e = s->data[s->topRight];
	}
	else
	{
		return ERR;
	}

	return OK;
}

棧的鏈式存儲結構——C語言描述

此時解決了順序存儲結構長度固化的缺點,並且棧的長度將不受限制。

棧的定義:

#define MAXSIZE 100
#define OK 1
#define ERR 0

typedef struct SNode
{
	int val;
	struct SNode* next;
}StackNode;

typedef struct LinkStack
{
	StackNode* top;
	int count;
} LinkStack, *LinkStackPtr;

Operation: 初始化棧空間

//初始化
bool InitLinkStack(LinkStack* s)
{
	if (!s)
		return ERR;

	s->top = NULL;
	s->count = 0;
	
	return OK;
}

Operation: 入棧

int Push(LinkStack* s, int e)
{
	//因鏈表結構通常動態變化,沒有長度限制,因此沒有基於鏈表棧,棧滿這一說
	if (!s)
		return ERR;

	StackNode* p = (StackNode*)malloc(sizeof(StackNode));
	if (!p)
		return ERR;
	memset(p, 0, sizeof(StackNode));

	p->val = e;
	p->next = s->top;
	s->top = p;
	s->count++;

	return OK;
}

Operation: 彈棧

int Pop(LinkStack* s, int* e)
{
	if (!s || !s->top)
		return ERR;

	StackNode* p = s->top;
	*e = s->top->val;
	s->top = s->top->next;
	s->count--;
	free(p);
	p = NULL;

	return OK;
}

Operation: 銷燬

//若棧存在,銷燬
int DestroyLinkStack(LinkStack* s)	//
{
	if (!s)
		return OK;

	while (s->top)
	{
		StackNode* p = s->top;
		s->top = s->top->next;
		free(p);
		p = NULL;
	}

	free(s);
	s = NULL;

	return OK;
}

Operation: 清空棧

//清空棧
int ClearLinkStack(LinkStack* s)
{
	if (!s)
		return OK;

	while (s->top)
	{
		StackNode* p = s->top;
		s->top = s->top->next;
		free(p);
	}
	s->count = 0;

	return OK;
}

Operation: 獲取棧頂元素

int GetTop(LinkStack* s, int* e)
{
	if (!s)
		return ERR;

	*e = s->top->val;

	return OK;
}


Operation 判斷是否爲空

bool IsStackEmpty(LinkStack* s)
{
	return (!s->top || !s) ? OK : ERR;
}

Operation 返回元素個數

int StackLength(LinkStack* s)
{
	return s->count;
}

聲明:代碼是本人敲的,除非表明出處。
參考:《大話數據結構》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章