什么是棧結(jié)構(gòu)
棧結(jié)構(gòu)是從數(shù)據(jù)的運(yùn)算來分類的,也就是說棧結(jié)構(gòu)具有特殊的運(yùn)算規(guī)則.而從數(shù)據(jù)的邏輯結(jié)構(gòu)來看,棧結(jié)構(gòu)是一種線性結(jié)構(gòu),如果從數(shù)據(jù)的存儲結(jié)構(gòu)來進(jìn)一步劃分,棧結(jié)構(gòu)包括兩類:
- 順序棧結(jié)構(gòu):即使用一組地址連續(xù)的內(nèi)存單元一次保存棧中的數(shù)據(jù),在程序中,可以定義一個指定大小的結(jié)構(gòu)數(shù)組來作為棧,序號為0的元素就是棧底,再定義一個變量top保存棧頂?shù)男蛱柧涂梢粤?
- 鏈?zhǔn)綏=Y(jié)構(gòu):即使用鏈表形式保存棧中的元素的值,鏈表首部(head引用所指向的元素)為棧頂,鏈表尾部(指向地址為null)為棧尾.

典型的棧結(jié)構(gòu),可以從上圖可以看出,在棧結(jié)構(gòu)中只能在一端進(jìn)行操作,也就是棧頂,另一端是棧尾,保存和取出數(shù)據(jù)都從棧頂進(jìn)行操作.這種操作叫(Last in First out ,LIFO)的原則進(jìn)行處理的.
看到棧的這種先進(jìn)后出,我們首先想到的是什么呢,子彈夾,對不對,子彈夾在放進(jìn)子彈的時候就是這樣,從上面一顆一顆的,這個叫入棧,取出子彈就是一顆一顆的彈出來,這個叫出棧!
- 入棧(Push):將數(shù)據(jù)保存到棧頂?shù)牟僮?進(jìn)行入棧操作前,先修改棧頂引用,使其向上移動一個元素位置,然后將數(shù)據(jù)保存到棧頂引用所指的位置.
- 出棧(Pop):將棧頂?shù)臄?shù)據(jù)彈出的操作,通過修改棧頂引用的,使其指向棧中的下一個元素.
準(zhǔn)備數(shù)據(jù)
static final int MAXLEN = 50;
class DATA3
{
String name;
int age;
}
class StackType
{
static final int MAXLEN = 50;
DATA3 [] data = new DATA3[MAXLEN+1];
int top;
}
在上述代碼中,我們定義棧結(jié)構(gòu)的最大長度MAXLEN,棧結(jié)構(gòu)的數(shù)據(jù)元素DATA3,我們定義了兩個屬性,一個名字,一個年齡.
StackType是我們定義的棧結(jié)構(gòu),其中data數(shù)組是我們存放棧的數(shù)據(jù)元素的數(shù)組,而top則是指向的棧結(jié)構(gòu)的棧頂,在數(shù)組中是從0開始存儲數(shù)據(jù)的,但是我們這里會從1這個位置存儲數(shù)據(jù).下標(biāo)0的位置不使用.
初始化棧結(jié)構(gòu)
在使用順序棧之前,首先要創(chuàng)建一個空的順序棧,也就是初始化一個順序棧.有如下步驟:
- 按符號常量SIZE指定的大小申請一片內(nèi)存空間,用來保存棧中的數(shù)據(jù)
- 設(shè)置棧頂引用的值為0,表示一個空棧
public StackType SYInit(){
StackType p;
if((p=new StackType())!=null){ //申請內(nèi)存
p.top = 0; //設(shè)置棧頂為0
return p; //返回棧引用
}
return null;
}
判斷是否是空棧
判斷是否是空棧可以直接通過判斷棧頂引用top是否為0就可以了知道了
public boolean STIsEmpty(StackType s){
if(s!=null){
return s.top == 0;
}
return false;
}
判斷是否是滿棧
判斷是否是漫展就是判斷棧頂引用top是否等于了它的最大值MAXLEN
public boolean SLIsFull(StackType s){
if(s!=null){
return s.top==MAXLEN;
}
return false;
}
清空棧
清空棧我們只需要把棧頂?shù)囊胻op設(shè)置為0就可以了
public void STClear(StackType s){
if(s!=null){
s.top=0;
}
}
釋放空間
在清空棧的方法里面,我們只是把棧頂設(shè)置為0,并沒有釋放空間,只需要把棧的引用指向null
public void STFree(StackType s){
if(s!=null){
s = null;
}
}
入棧
上面都是一些輔助操作,之所以把它們列在上面是因?yàn)槲覀兿旅嬗锌赡軙玫剿鼈?這里就是主要操作了.
入棧:把數(shù)據(jù)元素保存到棧結(jié)構(gòu)中,主要操作如下:
1.首先判斷棧是否已滿,如果不滿,則入棧
2.設(shè)置top=top+1,(棧頂引用加1,指向入棧地址)
3.將入棧元素指向top所在的位置
public int STPush(StackType s,DATA3 data){
if(SLIsFull(s)){ //判斷是否已經(jīng)滿了
System.out.println("你的彈夾已經(jīng)滿了! \n");
return 0;
}
s.data[++s.top] = data; //將元素保存到++s.top的位置
return 1;
}
出棧
出棧是棧的基本操作,與入棧相反,主要是從棧頂彈出一個操作,步驟如下:
1.首先判斷是否已經(jīng)是個空的了
2.將棧頂引用top所指向的元素返回
3.棧頂引用top減1,也就是指向下面的一個元素
public DATA3 STpop(StackType s){
if(STIsEmpty(s)){
System.out.println("你的彈夾沒有子彈了!");
return null;
}
return s.data[s.top--];
}
讀取結(jié)點(diǎn)
讀取棧的結(jié)點(diǎn),因?yàn)闂5牟僮鞫际菑囊欢俗x取,所以讀取結(jié)點(diǎn)也是棧頂結(jié)點(diǎn)的數(shù)據(jù),和出棧不同的是,這里只讀取不刪除
而出棧是彈出,就沒有了
public DATA3 STPeek(StackType s){
if(STIsEmpty(s)){
System.out.println("你的彈夾沒有子彈了!");
}
return s.data[s.top];
}
以上就是棧結(jié)構(gòu)的java代碼實(shí)現(xiàn)