java 棧 先進后出_數據結構: 先進后出——堆棧

棧是一種常用的數據結構,在生活中經常遇到這樣的例子,如鐵路調度站。本節將詳細介紹堆棧的實現過程。

算法點撥(順序棧)

棧是一種重要的數據結構。從數據結構的角度看,棧也是線性表,其特殊性在于棧的基本操作是線性表操作的子集,它們是操作受限的線性表,因此可以稱為限定性的數據結構。其操作是限定在表尾進行插入和刪除操作,允許操作的一端稱為棧頂。棧的結構如圖11.09所示:

圖11.09 棧的結構

實現棧首先需要實現一個棧內元素,關鍵代碼如下:

Java代碼

public class Stack {

private int maxSize;

private int stackArray[];

private int top=-1;

public Stack(int s){ //構造方法

maxSize=s;

stackArray=new int[maxSize];

}

}

說明:

上述代碼中,公共成員stackArray用于儲存棧中的數據,top用于存儲下一個數據元素的指針。對于棧的操作,無非是進行數據元素的入棧與出棧。

1.查找棧中元素

在進行棧中元素查找時,通常根據棧中元素的數據查找節點。要實現棧中元素的查找,首先需要解決的問題就是遍歷棧中的所有元素。可以從棧頂開始,利用循環的方式向下查找,只要不到棧底就可循環查找。

2.入棧操作

入棧操作前面說過,只能在棧頂操作。先將top指針向后移動一個單位,然后將想要入棧的數據元素放到原來top指針所指向的元素位置即可。這樣就實現了對棧的入棧操作。操作流程如圖11.10所示:

圖11.10 入棧操作示意圖

3.出棧操作

出棧操作和入棧操作的限定差不多,只是將整個過程反過來進行。先將數據元素釋放掉,然后在進行指針的操作,將棧頂指針top向前移動一個位置,使其位置在其原來所指向的位置。將棧頂元素的指針域的指針的指向位置變為原來元素的指向位置。出棧的操作流程如圖11.11所示

圖11.11 刪除節點示意圖

算法實現

棧是限定僅在表尾進行插入或刪除操作的線性表。因此對棧來說,表尾端有其特殊含義。

例11.3 實現棧的算法

首先需要實現自定義的數據元素類,該類的實現方法可以參看本節算法點撥中的代碼。

定義數據元素之后,開始棧的操作編程了。在類中,采用了push,pop,isEmpty,isfull,等方法進行入棧,出棧,判斷棧是否為空,判斷棧是否滿和對棧進行輸出。

向棧中添加數據的代碼如下:

Java代碼

public void push(int j){ //入棧方法

stackArray[++top]=j; //棧頂指針后移

}

對棧進行出棧的操作的代碼如下:

Java代碼

public int pop(){ //出棧方法

return stackArray[top--]; //棧頂指針前移

}

對棧是否為空和是否已滿以及輸出的判斷代碼如下:

Java代碼

public boolean isEmpty(){ //判斷棧是否為空

return (top==-1);

}

public boolean isFull(){ //判斷棧是否為滿

return (top==maxSize-1);

}

public void s(int d){ //輸出棧中內容

System.out.println("棧序列:");

for(int i=0;i

System.out.print(stackArray[i]+" ");

}

}

為了檢查創建棧操作的正確性,特別創建了一個名稱為StackTest的類,測試棧的入棧和出棧的操作,其關鍵代碼如下:

Java代碼

package stack;

public class StackTest {

public static void main(String[] args) {

int i=0;

Stack s=new Stack(20);

if(!s.isFull()){ //判斷棧是否滿,沒滿則調用入棧方法

s.push(100);i++;

s.push(23);i++;

s.push(45);i++;

s.push(78);i++;

s.s(i);

}

System.out.println("\n");

System.out.println("出棧序列:");

while(!s.isEmpty()){ //判斷棧是否為空,非空則調用出棧方法

int k=s.pop();

System.out.print(k+" ");

}

}

}

運行上面的代碼后,在控制臺輸出的信息如圖11.12所示。

圖11.12 運行測試類后在控制臺輸出的棧中的數據

算法點撥(兩棧共享空間)

在一個程序中如果需要同時使用具有相同數據類型的兩個棧時,我們覺得最直接的辦法就是,同時開辟出兩塊空間,建立兩個棧,但是這樣有時會出現,一個棧已經棧滿溢出了,而另一個棧確實空余出大量的存儲空間,這樣會造成大量存儲空間的浪費。現在我們可以找一種解決的方法,那就是:兩棧共享空間。我們使用一個數組來存儲兩個棧,讓一個棧的棧底為數組的始端,另一個棧的棧底為數組的末端,每個棧的棧頂都向中間延伸。兩棧共享空間的結構如圖11.13所示:

圖11.13 棧的結構

實現棧首先需要實現一個棧內元素,關鍵代碼如下:

Java代碼

public class Stack {

private int maxSize;

private int stackArray[];

private int top=-1;

public Stack(int s){ //構造方法

maxSize=s;

stackArray=new int[maxSize];

}

}

說明:

上述代碼中,公共成員stackArray用于儲存棧中的數據,top用于存儲下一個數據元素的指針。對于棧的操作,無非是進行數據元素的入棧與出棧。

1.查找共享空間棧中元素

在進行共享空間的棧中元素查找時,首先我們先要確定我們是要查找哪一個棧中的元素,然后的操作就和順序棧基本一樣了。

2.入棧操作

兩棧共享空間的入棧操作也是我們要先確定我們要對哪一個棧進行操作。入棧操作前面我們在順序棧中已經說過,只能在棧頂操作。例如我們選擇對棧一進行操作,先將top1指針向后移動一個單位,然后將想要入棧的數據元素放到原來top1指針所指向的元素位置即可。這樣就實現了對棧的入棧操作。操作流程如圖11.14所示:

圖11.14 入棧操作示意圖

3.出棧操作

對于共享空間棧的出棧操作和入棧操作的限定差不多,只是將整個過程反過來進行。先將數據元素釋放掉,然后在進行指針的操作,將棧頂指針top1向前移動一個位置,使其位置在其原來所指向的位置。將棧頂元素的指針域的指針的指向位置變為原來元素的指向位置。出棧的操作流程如圖11.15所示

圖11.15 刪除節點示意圖

算法實現

棧是限定僅在表尾進行插入或刪除操作的線性表。因此對棧來說,表尾端有其特殊含義。

例11.4 實現棧的算法

首先需要實現自定義的數據元素類,該類的實現方法可以參看本節算法點撥中的代碼。

定義數據元素之后,開始棧的操作編程了。在類中,采用了push,pop,isEmpty,isfull,s等方法進行入棧,出棧,判斷棧是否為空,判斷棧是否滿和對棧進行輸出。

向棧中添加數據的代碼如下:

Java代碼

public int bos(int i,int x){

int top1=0,top2=stackArray.length-1;

if(top1==top2){

System.out.println("元素溢出!");

}

if(i==1){ //如果操作棧1

return stackArray[++top1]=x;

}

if(i==2){ //如果操作棧2

return stackArray[--top2]=x;

}

return x; //返回插入的數

}

對棧進行出棧的操作的代碼如下:

Java代碼

public int bpop(int i){

if(i==1){ //如果是棧1

if(top1==-1){

System.out.println("下溢!");

}

return stackArray[top1--]; //棧頂回縮一位

}

if(i==2){ //如果是棧2

if(top2==stackArray.length){

System.out.println("下溢!");

}

return stackArray[top2++]; //棧頂后退一位

}

return i;

}

算法點撥(鏈棧)

棧的鏈接存儲被稱之為鏈棧。通常我們會用單鏈表進行對棧的存儲,因此其結構特點與單鏈表的結構特點基本相同。因為只能在棧頂進行插入和刪除操作,這樣我們就可以使用單鏈表的表頭作為棧的棧頂是最為方便的。其操作流程如圖11.16所示:

圖11.16 鏈棧流程圖

1.查找鏈棧中元素

對鏈棧進行查找操作,其本質上和對鏈表的查找操作是一樣的,只是限定了其只可以從一端進行操作,從表頭查起就可以了。

2.入棧操作

對于鏈棧的入棧操作,其實就是單鏈表的操作的簡化。我們只需要考慮棧頂的操作也就是第一位置的情況。操作流程如圖11.17所示:

圖11.17 入棧操作示意圖

3.出棧操作

對于鏈棧的出棧,其操作也是很簡單的,也是基于單鏈表的基本操作,也是僅僅是對第一位置的操作,不用考慮其他位置。出棧的操作流程如圖11.18所示

圖11.18 刪除節點示意圖

算法實現

鏈棧是限定僅在表尾進行插入或刪除操作的線性表。因此對棧來說,表尾端有其特殊含義。

例11.5 實現棧的算法

首先需要實現自定義的數據元素類,該類的實現方法可以參看本節算法點撥中的代碼。

定義數據元素之后,開始棧的操作編程了。在類中,采用了push,pop,isEmpty,isfull,s等方法進行入棧,出棧,判斷棧是否為空,判斷棧是否滿和對棧進行輸出。

實現鏈表首先需要實現一個節點類,關鍵代碼如下:

Java代碼

package stack;

public class Node {

public Node next; //指向下一個元素的指針域

public int values; //存儲元素的本身數據

public Node(){

int value = 0;

values=value;

}

}

說明:

上述代碼中,公共成員Value用于儲存節點本身的數據,Next用于存儲下一個節點的指針。

對于鏈棧的操作,無非是進行節點的插入和刪除操作對棧進行出棧的操作的代碼如下:

Java代碼

package stack;

public class Lstack {

Node top=new Node();

public void lpush(){

int x=0;

Node s=new Node(); //申請一個新的節點

s.values=x;

s.next=top; //將節點s插在棧頂

top=s;

}

public int lpop(){

int x=0;

Node p=new Node();

if(top==null){

System.out.println("下溢!");

}

x=top.values; //暫存棧頂元素

p=top; //將棧頂元素摘鏈

top=top.next;

return x;

}

}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452897.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452897.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452897.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Boot—07應用application.properties中的配置

方法1Value("${test.msg}") private String msg;方法2Autowired private Environment env; String value env.getProperty("test.msg");方法3RequestMapping(path"/${query.all}.json", methodRequestMethod.GET) ResponseBody public List&…

skip與direct模式區別 ,他們與CBP的關系

1 CBP表示殘差的編碼狀態,CBP一共6bit,低4位表示4個亮度8x8塊,第4位表示U,第五位表示V,如果相應的位為"1", 表示此塊有殘差系數,反之沒有殘差,此宏塊沒有被編碼.2 direct 是幀間宏塊的一種預測模式,而不是宏塊類型,而 S…

程序的裝入和鏈接過程

從用戶放入源程序進入操作系統到相應的裝程序在機器上運行,所經歷的主要階段有編譯階段 鏈接階段 裝入階段 和運行階段

[零基礎學JAVA]Java SE應用部分-34.Java常用API類庫

本季目標1、StringBuffer類 2、Runtime 類 3、包裝類與JDK 1.5的新特性——泛型 4、日期的操作類 5、Math類 6、Random類1、StringBuffer(重點) String 類的時候說過:String 類的內容一旦聲明則不可改變,改變的只是其地址。…

我所理解的機器學習

各位請移步到【http://www.cnblogs.com/cchHers/p/8945908.html】轉載于:https://www.cnblogs.com/cchHers/p/8933042.html

protobuf java文檔_Java中使用Protobuf

gradle依賴庫:implementation com.google.protobuf:protobuf-java:3.4.0implementation com.google.protobuf:protobuf-java-util:3.4.00.編寫.proto文件,編譯生成對應Java源文件:syntax "proto2";option java_generic_services …

python 數組和列表的區別

Python沒有數組: 只有元組(tuple)和列表(list);元組一旦創建不可改變,例如:aatuple(1,2,3);元組不能追加(append)元素,彈出(pop)元素等;只能對元組中的元素進行索引aa[0],不能對其中…

內存空間 邏輯地址空間 相對地址 絕對地址

內存空間(物理空間或絕對空間):由一系列存儲單元所限定 的地址范圍。 邏輯地址空間(地址空間):由程序中邏輯地址組成的地址范圍。 相對地址(邏輯地址):用戶程序經編譯后…

多租戶表設計

2019獨角獸企業重金招聘Python工程師標準>>> multi-tenant-databases-in-the-cloudtips-amp-tricks-to-build-multi-tenant-databases-with-sql-databases團隊開發框架實戰—多租戶支持轉載于:https://my.oschina.net/yangjiandong/blog/1612626

java 讀取webapp文件_在Java Webapp和Java Normal應用中讀取公共外部屬性文件

但是,我們有以下一些特殊要求,Webapp將部署到tomcat。格式為.jar的普通Java應用程序將放在/ myapp文件夾下myappConfig.property文件將放置在/ myapp下客戶端計算機上的目錄結構/myapp/myapp.jar/assests/myappConfig.property/tomcat/webapps/myapp.war…

CSS實現樹形結構 + js加載數據

看到一款樹形結構&#xff0c;比較喜歡它的樣式&#xff0c;就參照它的外觀自己做了一個&#xff0c;練習一下CSS。 做出來的效果如下&#xff1a; 拉莫小學 一年級 一班二班二年級三年級 一班二班三班樹的dom結構&#xff1a; <div class"tree"><ul><…

python中__init__函數以及參數self

1.class類包含&#xff1a; 類的屬性&#xff1a;類中所涉及的變量 類的方法&#xff1a;類中函數 2. _init_函數&#xff08;方法&#xff09; 首先說一下&#xff0c;帶有兩個下劃線開頭的函數是聲明該屬性為私有,不能在類地外部被使用或直接訪問。init函數&#xff08;方…

程序的裝入方式

1 絕對裝入方式 2 可重定位裝入方式 3 動態運行時裝入方式

嵌套集合模型(Nested set model)介紹

原文鏈接&#xff1a;www.pilishen.com/posts/an-in… 此文檔是 nestedset-無限分類正確姿勢的擴展閱讀 本文翻譯自維基百科Nested set model nested set model(嵌套集合模型)是一種在關系型數據庫中表示nested sets&#xff08;嵌套集合&#xff09; 的特殊技術。[nested sets…

互聯網商業模式:增值還是減值?

網絡可以為服務增值&#xff0c;這是人們的共識。不但是增值&#xff0c;而且是按照用戶的平方增值&#xff0c;這是梅特卡夫定律說的。 我認為&#xff0c;網絡也可以為服務減值&#xff0c;是按照服務提供商的數量的平方減值。如果按用戶增值是網絡的第一定律&#xff0c;這…

程序的鏈接方式

1 靜態鏈接 2 裝入時動態鏈接 3 運行時動態鏈接

Django中--自定義模型管理器類

BookInfo.objects.all()->objects是一個什么東西呢&#xff1f; 答&#xff1a;objects是models.Manger類的一個對象&#xff0c;是Django幫我自動生成的管理器對象&#xff0c;通過這個管理器可以實現對數據的查詢。 自定義管理器之后Django不再幫我們生成默認的objects管…

字符驅動之按鍵(四:poll機制)

1 采用之前的中斷按鍵法&#xff0c;程序會一直在read函數中死循環。2 使用了poll之后&#xff0c;在一段時間內如果有按鍵按下就會返回&#xff0c;如果沒有按鍵按下等時間到再返回。3 4 應用程序的open,read,write,poll分別對應了驅動程序的open,read,write和poll。5…

第二章 API的理解和使用

2.1.1全局命令 Key * 查看所有鍵&#xff0c;(慎用&#xff0c;會把所有鍵都遍歷一次并列出) Dbsize 查看鍵總數&#xff0c;不會遍歷所有鍵&#xff0c;只是從內置函數中讀取一個數 Exists [key] 檢查鍵是否存在 Del [key] 刪除鍵 Expire [key] [seconds] 設置鍵過期時間 Type…

java uuid 線程安全_java – 在多線程應用程序中生成相同的UUID

我使用UUID.randomUUID().toString()將一個唯一值附加到最終存儲在數據庫中的字符串,并對其具有唯一約束但是因為我的應用程序是多線程的,所以執行在UUID生成的同時發生,并且最終將相同的UUID附加到字符串并且持久性失敗.有沒有更好的方法來生成隨機字符串,即故障安全方法.我嘗…