成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

動(dòng)圖演示:手?jǐn)]堆棧的兩種實(shí)現(xiàn)方法!

開(kāi)發(fā) 前端
正式開(kāi)始之前,先和各位朋友聊聊公眾號(hào)后期的一些打算,后面的文章計(jì)劃寫一些關(guān)于數(shù)據(jù)結(jié)構(gòu)和算法的內(nèi)容,原因很簡(jiǎn)單「底層結(jié)構(gòu)決定上層建筑嘛」,對(duì)于框架滿天飛的今天,我們不止要學(xué)習(xí)如何使用框架,更要了解它的原理以及底層數(shù)據(jù)結(jié)構(gòu),只有這樣我們才能更好的應(yīng)用它。

 [[343379]]

本文轉(zhuǎn)載自微信公眾號(hào)「Java中文社群」,作者磊哥  。轉(zhuǎn)載本文請(qǐng)聯(lián)系Java中文社群公眾號(hào)。  

正式開(kāi)始之前,先和各位朋友聊聊公眾號(hào)后期的一些打算,后面的文章計(jì)劃寫一些關(guān)于數(shù)據(jù)結(jié)構(gòu)和算法的內(nèi)容,原因很簡(jiǎn)單「底層結(jié)構(gòu)決定上層建筑嘛」,對(duì)于框架滿天飛的今天,我們不止要學(xué)習(xí)如何使用框架,更要了解它的原理以及底層數(shù)據(jù)結(jié)構(gòu),只有這樣我們才能更好的應(yīng)用它。

當(dāng)然,除了上述原因之外,還有一個(gè)重要因素是為了搞定面試。

隨著軟件開(kāi)發(fā)行業(yè)競(jìng)爭(zhēng)的日益激烈,面試的難度也在逐漸增加,因?yàn)槠髽I(yè)要從眾多的面試人中選出最優(yōu)秀的人,只能提高面試的難度,而算法和數(shù)據(jù)結(jié)構(gòu)比較燒腦的硬核技能之一,自然也就成了面試的首選科目。并且隨著時(shí)間的推移,算法和數(shù)據(jù)結(jié)構(gòu)出現(xiàn)的頻率和占比也會(huì)不斷增加,因此為了順應(yīng)時(shí)代發(fā)展的潮流,我們也要做一些調(diào)整,所以在后面的一些文章中,我會(huì)陸續(xù)更新一些關(guān)于算法和數(shù)據(jù)結(jié)構(gòu)的文章,希望大家能夠喜歡。

PS:當(dāng)然隨著智能系統(tǒng)的普及(如今日頭條和抖音),算法和數(shù)據(jù)結(jié)構(gòu)在企業(yè)中應(yīng)用也越來(lái)越多,因此學(xué)習(xí)算法和數(shù)據(jù)結(jié)構(gòu)也是迫在眉睫的事了。

棧定義

棧(Stack)又叫堆棧(簡(jiǎn)稱棧),它是在同一端進(jìn)行插入和刪除數(shù)據(jù)的線性表。

棧是最基礎(chǔ)也是最常見(jiàn)的數(shù)據(jù)結(jié)構(gòu)之一,它的數(shù)據(jù)結(jié)構(gòu)和操作流程如下圖所示:

其中,允許進(jìn)行插入和刪除的一端叫作棧頂(Top),另一端叫作棧底(Bottom),棧底固定,棧頂浮動(dòng)。

當(dāng)棧中的元素為零時(shí),該棧叫作空棧。添加數(shù)據(jù)時(shí)一般叫作入棧或進(jìn)棧(Push),刪除數(shù)據(jù)叫作出棧或退棧(Pop)。棧是后進(jìn)先出(Last In First Out,LIFO)的線性表。

物理結(jié)構(gòu) & 邏輯結(jié)構(gòu)

在手?jǐn)]算法之前,我們先來(lái)認(rèn)識(shí)一下數(shù)據(jù)結(jié)構(gòu)中的兩個(gè)重要概念:物理結(jié)構(gòu)和邏輯結(jié)構(gòu)。

當(dāng)談到“物理”和“邏輯”一詞時(shí),我們可以會(huì)想到數(shù)據(jù)庫(kù)中的邏輯刪除和物理刪除。

所謂的物理刪除是指通過(guò)刪除命令真實(shí)的將數(shù)據(jù)從物理結(jié)構(gòu)中刪除的過(guò)程;而邏輯刪除是指通過(guò)修改命令將數(shù)據(jù)更改為“已刪除”的狀態(tài),并非真實(shí)的刪除數(shù)據(jù)。

這里的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)和上面的概念類似,所謂的物理結(jié)構(gòu)是指可以將數(shù)據(jù)存儲(chǔ)在物理空間中,比如數(shù)組和鏈表都屬于物理數(shù)據(jù)結(jié)構(gòu);而邏輯結(jié)構(gòu)則是用于描述數(shù)據(jù)間的邏輯關(guān)系的,比如本文要講的棧就屬于邏輯結(jié)構(gòu)。

可能有些人看到這里就蒙了,沒(méi)關(guān)系,我這里舉一個(gè)例子你就明白了。

如果用人來(lái)表示物理結(jié)構(gòu)和邏輯結(jié)構(gòu)的話,那么真實(shí)存在的有血有肉的人就屬于物理結(jié)構(gòu),而人的思想和信念就屬于邏輯結(jié)構(gòu)了。

自定義棧I:數(shù)組實(shí)現(xiàn)

通過(guò)上面的內(nèi)容,我們知道了棧屬于邏輯結(jié)構(gòu),因此它的實(shí)現(xiàn)方式就可以有很多種了,比如數(shù)組的實(shí)現(xiàn)方式或者是鏈表的實(shí)現(xiàn)方式。那么我們就先用數(shù)組實(shí)現(xiàn)一下,棧的主要方法有:

① 定義結(jié)構(gòu)

那么我們先來(lái)定義它的結(jié)構(gòu):

  1. public class MyStack<E> { 
  2.     private Object[] value = null; // 棧存儲(chǔ)容器 
  3.     private int top = -1; // 棧頂(的指針) 
  4.     private int maxSize = 0; // 棧容量 
  5.  
  6.     // 構(gòu)造函數(shù)(初始化默認(rèn)容量) 
  7.     MyStack() { 
  8.         this.maxSize = 10; 
  9.     } 
  10.  
  11.     // 有參構(gòu)造函數(shù) 
  12.     MyStack(int initSize) throws Exception { 
  13.         if (initSize <= 0) { 
  14.             throw new Exception("棧容量必須大于 0"); 
  15.         } else { 
  16.             value = new Object[initSize]; 
  17.             maxSize = initSize; 
  18.             top = -1; 
  19.         } 
  20.     } 

其中棧中數(shù)據(jù)會(huì)存儲(chǔ)在 Object[] value 數(shù)組中,top 變量代表?xiàng)m數(shù)闹羔槪鋵?shí)存儲(chǔ)的是棧頂元素的下標(biāo),會(huì)隨著入棧不斷變化(后進(jìn)先出),maxSize 表示棧的最大容量。

② 入棧

此方法是給棧添加數(shù)據(jù)的,實(shí)現(xiàn)代碼如下:

  1. // 入棧(數(shù)據(jù)添加) 
  2. public boolean push(E e) throws Exception { 
  3.     if (maxSize - 1 == top) { 
  4.         throw new Exception("入棧失敗,棧已滿"); 
  5.     } else { 
  6.         value[++top] = e; 
  7.         return true
  8.     } 

每次當(dāng)有數(shù)據(jù)插入時(shí),只需在數(shù)組中添加一個(gè)值,并將棧頂?shù)南聵?biāo) +1 即可。

入棧操作如下圖所示:

③ 出棧

此方法是刪除棧中的數(shù)據(jù)的,實(shí)現(xiàn)代碼如下:

  1. // 數(shù)據(jù)移除(出棧) 
  2. public E pop() throws Exception { 
  3.     if (top <= -1) { 
  4.         throw new Exception("移除失敗,棧中已無(wú)數(shù)據(jù)"); 
  5.     } else { 
  6.         return (E) value[top--]; 
  7.     } 

出棧只需刪除數(shù)組中棧頂數(shù)據(jù)(最后加入的數(shù)據(jù)),并修改棧頂下標(biāo) -1 即可。

出棧操作如下圖所示:

④ 數(shù)據(jù)查詢

除了以上操作方法之外,我們還需要添加一個(gè)查詢棧頂數(shù)據(jù)的方法:

  1. // 數(shù)據(jù)查詢 
  2. public E peep() throws Exception { 
  3.     if (top <= -1) { 
  4.         throw new Exception("移除失敗,棧中已無(wú)數(shù)據(jù)"); 
  5.     } else { 
  6.         return (E) value[top]; 
  7.     } 

⑤ 代碼測(cè)試

到此為止棧的數(shù)據(jù)結(jié)構(gòu)就已經(jīng)實(shí)現(xiàn)完了,接下來(lái)我們來(lái)測(cè)試一下:

  1. // 代碼測(cè)試 
  2. public static void main(String[] args) throws Exception { 
  3.     MyStack stack = new MyStack(10); 
  4.     stack.push("Hello"); 
  5.     stack.push("Java"); 
  6.     System.out.println(stack.peep()); 
  7.     stack.pop(); 
  8.     System.out.println(stack.pop()); 

以上程序的執(zhí)行結(jié)果為:

Java

Hello

從上述代碼可以看出,我們添加棧的順序是 Hello、Java 而輸出的順序是 Java、 Hello 符合棧的定義(后進(jìn)先出)。

自定義棧II:鏈表實(shí)現(xiàn)

除了數(shù)組之外,我們可以還可使用鏈表來(lái)實(shí)現(xiàn)棧結(jié)構(gòu),它的實(shí)現(xiàn)稍微復(fù)雜一些,我們先來(lái)看鏈表本身的數(shù)據(jù)結(jié)構(gòu):

使用鏈表實(shí)現(xiàn)棧的流程如下:

也就是說(shuō),入棧時(shí)我們將數(shù)據(jù)存儲(chǔ)在鏈表的頭部,出棧時(shí)我們從頭部進(jìn)行移除,并將棧頂指針指向原頭部元素的下一個(gè)元素,實(shí)現(xiàn)代碼如下。

我們先來(lái)定義一個(gè)鏈表節(jié)點(diǎn):

  1. public class Node { 
  2.     Object value; // 每個(gè)節(jié)點(diǎn)的數(shù)據(jù) 
  3.     Node next; // 下一個(gè)節(jié)點(diǎn) 
  4.  
  5.     public Node(Object value) { 
  6.         this(value, null); 
  7.     } 
  8.  
  9.     /** 
  10.      * 創(chuàng)建新節(jié)點(diǎn) 
  11.      * @param value 當(dāng)前節(jié)點(diǎn)數(shù)據(jù) 
  12.      * @param next  指向下一個(gè)節(jié)點(diǎn)(頭插法) 
  13.      */ 
  14.     public Node(Object value, Node next) { 
  15.         this.value = value; 
  16.         this.next = next
  17.     } 

接下來(lái)我們使用鏈表來(lái)實(shí)現(xiàn)一個(gè)完整的棧:

  1. public class StackByLinked { 
  2.  
  3.     private Node top = null; // 棧頂數(shù)據(jù) 
  4.     private int maxSize = 0; // 棧最大容量 
  5.     private int leng = 0; // 棧實(shí)際容量 
  6.  
  7.     public StackByLinked(int initSize) throws Exception { 
  8.         if (initSize <= 0) { 
  9.             throw new Exception("棧容量不能小于等于0"); 
  10.         } 
  11.         top = null
  12.         maxSize = initSize; 
  13.         leng = 0; 
  14.     } 
  15.  
  16.     /** 
  17.      * 容量是否已滿 
  18.      * @return 
  19.      */ 
  20.     public boolean isFull() { 
  21.         return leng >= maxSize; 
  22.     } 
  23.  
  24.     /** 
  25.      * 是否為空 
  26.      * @return 
  27.      */ 
  28.     public boolean isEmpty() { 
  29.         return leng <= 0; 
  30.     } 
  31.  
  32.     /** 
  33.      * 入棧 
  34.      * @param val 
  35.      * @return 
  36.      * @throws Exception 
  37.      */ 
  38.     public boolean push(Object val) throws Exception { 
  39.         if (this.isFull()) { 
  40.             // 容量已滿 
  41.             throw new Exception("容量已滿"); 
  42.         } 
  43.         top = new Node(val, top); // 存入信息,并將當(dāng)前節(jié)點(diǎn)設(shè)置為頭節(jié)點(diǎn) 
  44.         leng++; 
  45.         return true
  46.     } 
  47.  
  48.     /** 
  49.      * 出棧(移除) 
  50.      * @return 
  51.      * @throws Exception 
  52.      */ 
  53.     public Node pop() throws Exception { 
  54.         if (this.isEmpty()) { 
  55.             throw new Exception("棧為空,無(wú)法進(jìn)行移除操作"); 
  56.         } 
  57.         Node item = top; // 返回當(dāng)前元素 
  58.         top = top.next
  59.         leng--; 
  60.         return item; 
  61.     } 
  62.  
  63.     /** 
  64.      * 查詢棧頂信息 
  65.      * @return 
  66.      */ 
  67.     public Node peek() throws Exception { 
  68.         if (isEmpty()) { 
  69.             throw new Exception("你操作的是一個(gè)空棧"); 
  70.         } 
  71.         return top
  72.     } 
  73.  
  74.     // 代碼測(cè)試 
  75.     public static void main(String[] args) throws Exception { 
  76.         StackByLinked stack = new StackByLinked(10); 
  77.         stack.push("Hello"); 
  78.         stack.push("Java"); 
  79.         System.out.println(stack.peek().value); 
  80.         stack.pop(); 
  81.         System.out.println(stack.pop().value); 
  82.     } 

以上程序的執(zhí)行結(jié)果是:

Java

Hello

總結(jié)

本文我們使用了數(shù)組和鏈表等物理結(jié)構(gòu)來(lái)實(shí)現(xiàn)了棧,當(dāng)然我們也可以使用其他容器來(lái)實(shí)現(xiàn),比如 Java 中的 List,我們只需要保證在操作棧時(shí)是后進(jìn)先出的執(zhí)行順序,并且至少包含 3 個(gè)重要方法:入棧、出棧和查詢棧頂元素就可以了。

最后

算法和數(shù)據(jù)結(jié)構(gòu)的學(xué)習(xí)是 3 分學(xué) 7 分練,只看不練是沒(méi)辦法學(xué)好算法的,而且學(xué)習(xí)算法和數(shù)據(jù)結(jié)構(gòu)是一個(gè)循序漸進(jìn)的過(guò)程,短時(shí)間內(nèi)不會(huì)有明顯的收效。因?yàn)檫@些算法經(jīng)過(guò)了幾百年的發(fā)展和積累才得以流傳下來(lái)的,所以想要“玩得轉(zhuǎn)”還需要一點(diǎn)耐心。

這里給你講一個(gè)學(xué)習(xí)算法的“秘訣”:看不懂的知識(shí)要反復(fù)看,如果反復(fù)看還是看不懂,那么別著急,休息一下再繼續(xù)看!相信我,對(duì)于學(xué)習(xí)算法這件事,所有人的過(guò)程都是一樣的。

 

責(zé)任編輯:武曉燕 來(lái)源: Java中文社群
相關(guān)推薦

2012-10-16 09:40:38

洗牌算法

2010-10-14 14:33:15

MySQL多表聯(lián)查

2011-08-09 13:50:01

iPhone動(dòng)畫(huà)UIView

2015-08-07 14:34:11

Windows 10安裝補(bǔ)丁

2013-06-27 09:26:50

Android界面刷新

2022-02-09 07:03:01

SpringNacos服務(wù)注冊(cè)

2010-04-25 17:34:30

負(fù)載均衡實(shí)現(xiàn)

2020-10-21 08:17:11

隊(duì)列數(shù)據(jù)

2011-06-23 09:07:16

2020-08-03 08:10:52

UDPTCP通信

2022-02-21 08:18:38

option編程模式

2010-07-14 10:30:26

Perl多線程

2017-11-16 09:20:20

內(nèi)存虛擬化技術(shù)

2010-09-17 09:37:27

Java安裝方法

2021-12-08 10:47:35

RabbitMQ 實(shí)現(xiàn)延遲

2009-09-25 14:04:09

Hibernate eHibernate h

2009-10-26 10:30:57

VB.NET處理FTP

2010-11-19 11:57:15

Oracle密碼丟失

2011-03-03 17:00:37

pure-ftpdchroot

2010-07-05 16:37:19

UML類圖
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 久久精品视频9 | 亚洲 欧美 日韩在线 | 中文字幕在线剧情 | 久久久久中文字幕 | 国产精品日韩一区二区 | 久久久国产一区 | 超碰精品在线 | 狠狠色综合网站久久久久久久 | 91麻豆精品国产91久久久久久 | 亚洲视频中文字幕 | 成人区一区二区三区 | 天堂一区二区三区 | av大片在线 | 涩涩导航 | 国产人成精品一区二区三 | 综合色站导航 | 国产精品大片 | 日韩国产一区 | 成年人网站国产 | 久久精品一区二区三区四区 | 香蕉国产在线视频 | 日本久久综合 | 日日噜 | 国产一区亚洲 | 91精品国产综合久久久久 | 国产一级在线 | 国产美女精品 | 综合色久 | 国产精品一区在线观看 | 亚洲一级毛片 | 国产成人精品一区二区 | 黄色在线免费观看视频网站 | 免费在线观看av的网站 | 在线视频一区二区三区 | 黄视频网址 | 国产精品色 | 国产精品视频在线播放 | 在线观看中文字幕视频 | 色偷偷人人澡人人爽人人模 | 成人小视频在线观看 | 欧美福利|