數據結構
數據結構有什麼用?
當你用着java裏面的容器類很爽的時候,你有沒有想過,怎麼ArrayList就像一個無限擴充的數組,也好像鏈表之類的。好用嗎?好用,這就是數據結構的用處,只不過你在不知不覺中使用了。
現實世界的存儲,我們使用的工具和建模。每種數據結構有自己的優點和缺點,想想如果Google的數據用的是數組的存儲,我們還能方便地查詢到所需要的數據嗎?而算法,在這麼多的數據中如何做到最快的插入,查找,刪除,也是在追求更快。
常見的數據結構
數據存儲的常用結構有:棧、隊列、數組、鏈表和紅黑樹。我們分別來了解一下:
棧
- 棧:stack,又稱堆棧,它是運算受限的線性表,其限制是僅允許在標的一端進行插入和刪除操作,不允許在其他任何位置進行添加、查找、刪除等操作。
簡單的說:採用該結構的集合,對元素的存取有如下的特點
-
先進後出(即,存進去的元素,要在後它後面的元素依次取出後,才能取出該元素)。例如,子彈壓進彈夾,先壓進去的子彈在下面,後壓進去的子彈在上面,當開槍時,先彈出上面的子彈,然後才能彈出下面的子彈。
-
棧的入口、出口的都是棧的頂端位置。
這裏兩個名詞需要注意:
- 壓棧:就是存元素。即,把元素存儲到棧的頂端位置,棧中已有元素依次向棧底方向移動一個位置。
- 彈棧:就是取元素。即,把棧的頂端位置元素取出,棧中已有元素依次向棧頂方向移動一個位置。
隊列
- 隊列:queue,簡稱隊,它同堆棧一樣,也是一種運算受限的線性表,其限制是僅允許在表的一端進行插入,而在表的另一端進行刪除。
簡單的說,採用該結構的集合,對元素的存取有如下的特點:
- 先進先出(即,存進去的元素,要在後它前面的元素依次取出後,才能取出該元素)。例如,小火車過山洞,車頭先進去,車尾後進去;車頭先出來,車尾後出來。
- 隊列的入口、出口各佔一側。例如,下圖中的左側爲入口,右側爲出口。
數組
- 數組:Array,是有序的元素序列,數組是在內存中開闢一段連續的空間,並在此空間存放元素。就像是一排出租屋,有100個房間,從001到100每個房間都有固定編號,通過編號就可以快速找到租房子的人。
簡單的說,採用該結構的集合,對元素的存取有如下的特點:
-
查找元素快:通過索引,可以快速訪問指定位置的元素
-
增刪元素慢
-
指定索引位置增加元素:需要創建一個新數組,將指定新元素存儲在指定索引位置,再把原數組元素根據索引,複製到新數組對應索引的位置。如下圖:
-
指定索引位置刪除元素:需要創建一個新數組,把原數組元素根據索引,複製到新數組對應索引的位置,原數組中指定索引位置元素不復制到新數組中。如下圖
鏈表
- 鏈表:linked list,由一系列結點node(鏈表中每一個元素稱爲結點)組成,結點可以在運行時i動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。我們常說的鏈表結構有單向鏈表與雙向鏈表,那麼這裏給大家介紹的是單向鏈表。
簡單的說,採用該結構的集合,對元素的存取有如下的特點:
-
多個結點之間,通過地址進行連接。例如,多個人手拉手,每個人使用自己的右手拉住下個人的左手,依次類推,這樣多個人就連在一起了。
-
查找元素慢:想查找某個元素,需要通過連接的節點,依次向後查找指定元素
-
增刪元素快:
- 增加元素:只需要修改連接下個元素的地址即可。
- 刪除元素:只需要修改連接下個元素的地址即可。
紅黑樹
- 二叉樹:binary tree ,是每個結點不超過2的有序樹(tree) 。
簡單的理解,就是一種類似於我們生活中樹的結構,只不過每個結點上都最多隻能有兩個子結點。
二叉樹是每個節點最多有兩個子樹的樹結構。頂上的叫根結點,兩邊被稱作“左子樹”和“右子樹”。
如圖:
我們要說的是二叉樹的一種比較有意思的叫做紅黑樹,紅黑樹本身就是一顆二叉查找樹,將節點插入後,該樹仍然是一顆二叉查找樹。也就意味着,樹的鍵值仍然是有序的。
紅黑樹的約束:
-
節點可以是紅色的或者黑色的
-
根節點是黑色的
-
葉子節點(特指空節點)是黑色的
-
每個紅色節點的子節點都是黑色的
-
任何一個節點到其每一個葉子節點的所有路徑上黑色節點數相同
紅黑樹的特點:
速度特別快,趨近平衡樹,查找葉子元素最少和最多次數不多於二倍