數據結構隨筆——棧,及STL中的

一、棧的定義

在我們軟件應用中,棧這種後進先出數據結構的應用是非常普遍的。比如你用瀏覽器上網時,不管什麼瀏覽器都有一一個“後退”鍵,你點擊後可以按訪問順序的逆序加載瀏覽過的網頁。這就是棧的一個實際運用。

棧(stack)是僅限在表尾進行插入和刪除的線性表

二、棧的順序存儲結構及代碼實現

首先來看,棧的定義,這裏是用數組實現棧,實際上用鏈表也可以實現,稱爲鏈式棧。

個人認爲棧這部分重點在於看懂源碼,動手實現起來是十分容易的。

#define datatype int 
#define maxsize 1024
struct stack
{
	datatype data[maxsize];
	int top; //棧頂指針,1個元素就是0,2個就是1,以此類推
};

棧的初始化

首先要對這個結構體申請空間,然後傳回該結構體的指針。

stack* init_stack() //返回類型爲結構體指針的函數,初始化棧
{
	stack* s;
	s = (stack*)malloc(sizeof(stack));
	if (!s)
	{
		cout << "空間不足,申請失敗" << endl;
		return NULL;
	}
	else 
	{
		s->top = -1;//定義棧底爲-1
		return s;
	}
}

入棧

要判斷是否爲棧滿,然後將該元素壓入。

int push(stack* s, datatype x) //入棧
{
	if (s->top == maxsize - 1)
	{
		cout << "棧滿,無法入棧" << endl;
		return 0;
	}
	else
	{
		s->data[++s->top] = x;
		return 1;
	}
}

出棧

要判斷是否爲空棧,然後將該元素的值傳給指針。(改變函數,返回該值也可以)。

int pop(stack* s, datatype* e) //出棧一個元素,並且用e返回其值
{
	if (empty_stack(s))
	{
		cout << "棧空,無法出棧" << endl;
		return 0;
	}
	else
	{
		*e = s->data[s->top--];
		return 1;
	}
}

判斷空棧

這個很簡單,看top值是否爲-1即可。

int empty_stack(stack* s) //判斷空棧
{
	if (s->top == -1)
		return 1; //爲空
	else
		return 0;
}

獲得棧頂元素

datatype gettop(stack* s)
{
	if (empty_stack(s))
	{
		cout << "棧空,無棧頂元素" << endl;
		return 0;
	}
	else
		return s->data[s->top]; //返回棧頂
}

顯示棧中所有元素,自上而下

void print_stack(stack* s) //顯示所有元素
{
	if (empty_stack(s))
	{
		cout << "棧空,無元素" << endl;
		return;
	}
	else
	{
		for (int i = s->top; i >= 0; i--)
			cout << s->data[i] << endl;
		return;
	}
}

至於返回棧中元素數量,這個可以定義一個函數返回top+1的值,即爲元素個數。同理,刪除這個棧中所有元素,只需要把top的值修改爲-1即可。銷燬棧,釋放棧空間即可。在此不多贅述。

三、STL中的<stack>

這就十分簡單了,函數都封裝好了。C++中stl的stack(棧)以其他容器(deque默認,vector,list)作爲底層數據結構而形成,只是修改了接口以滿足棧的特性。

#include<stack>//棧
stack<int>  s;//參數也是數據類型,這是棧的定義方式
s.empty()//如果棧爲空返回true,否則返回false  
s.size()//返回棧中元素的個數  
s.pop()//刪除棧頂元素但不返回其值  
s.top()//返回棧頂的元素,但不刪除該元素  
s.push(X)//在棧頂壓入新元素 ,參數X爲要壓入的元素

四、兩棧共享空間

數組有兩個端點,兩個棧有兩個棧底,讓一個棧的棧底爲0,另一個爲棧的棧末端,即爲數組大小的n-1處。這樣,兩個棧都增加元素都是往中間處靠攏。

在這裏插入圖片描述

棧1爲空時,就是top1等於-1時,而當top2等於n時,即是棧2爲空時,那什麼時候棧滿呢?

若棧2是空棧,棧1的top1等於n-1時,就是棧1滿了。反之,當棧1爲空棧時,top2 等於0時,爲棧2滿。但更多的情況,其實就是,兩個指針之間相差1時,即top1 + 1 == top2 爲棧滿。

事實上,使用這樣的數據結構,通常都是當兩個棧的空間需求有相反關係時,也就是一個棧增長時另一個棧在縮短的情況。當然,這只是針對兩個具有相同數據類型的棧的一一個設計上的技巧,如果是不相同數據類型的棧,這種辦法不但不能更好地處理問題,反而會使問題變得更復雜。

定義

#define datatype int 
#define maxsize 1024
typedef struct
{
  datatype data[maxsize];
	int top1;
	int top2;
}doublestack;

壓入元素

在壓入和刪除時,就只是需要判斷一下對哪個棧操作而已。

int double_stack_push(doublestack* s, int stacknumber, datatype x) 
//結構體指針,要操作的棧,要壓入的元素
{
	if (s->top1 + 1 == s->top2)
		return 0; //棧滿
	else
	{
		if (stacknumber == 1)
			s->data[++s->top1] = x; //先自加再賦值
		else if(stacknumber==2)
			s->data[--s->top2] = x;
		return 1;
	}
}

刪除元素

int double_stack_pop(doublestack* s, int stacknumber,datatype* e)
{
	if (stacknumber == 1)
	{
		if (s->top1 == -1)
			return 0; //棧1爲空
		else
			*e = s->data[s->top1--];//先出棧再自減
	}
	else if (stacknumber == 2)
	{
		if (s->top1 == maxsize)
			return 0; //棧1爲空
		else
			*e = s->data[s->top2++];//先出棧再自加
	}
	return 1;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章