站在巨人的肩膀上學數據結構,不飄也難啊!

前言

今天咱們來學一下數據結構方面的知識,對紮實 Java 的基本功很是有用,學會了就會有一種自帶大佬的感受,嘿嘿。數據結構,也就是 Data Structure,是一種存儲數據的結構體,數據與數據之間存在着必定的關係,這樣的關係有數據的邏輯關係、數據的存儲關係和數據的運算關係,整理一份MySQL學習筆記,數據結構和MySQL仍是離不開的。在 Java 中,數據結構通常能夠分爲兩大類:線性數據結構和非線性數據結構。哈哈,這個名字頗有靈魂吧?面試

線性數據結構

1)數組

一眼看上去就知道的,像 String []、int [] 這種;還有須要看兩眼才能看透的(看源碼了),像 ArrayList,內部對數組進行了封裝。算法

數組這種數據結構最大的好處,就是能夠根據下標(或者叫索引)進行操做,插入的時候能夠根據下標直接插入到具體的位置,但與此同時,後面的元素就須要所有向後移動,須要移動的數據越多,就越累。數據庫

假設如今已經有了一個 ArrayList 了,準備在第 4 個位置(下標爲 3)上添加一個元素 55。數組

站在巨人的肩膀上學數據結構,不飄也難啊!

此時 ArrayList 中國 5 個位置之後的元素將會向後移動。數據結構

站在巨人的肩膀上學數據結構,不飄也難啊!

準備把 23 從 ArrayList 中移除。ide

站在巨人的肩膀上學數據結構,不飄也難啊!

此時下標爲 七、八、9 的元素往前挪。學習

站在巨人的肩膀上學數據結構,不飄也難啊!

簡單總結一下 ArrayList 的時間複雜度,方便你們在學習的時候做爲參考。優化

一、經過下標(也就是 get(int index))訪問一個元素的時間複雜度爲 O(1),由於是直達的,不管數據增大多少倍,耗時都不變。動畫

二、添加一個元素(也就是 add())的時間複雜度爲 O(1),由於直接添加到末尾。3d

三、刪除一個元素的時間複雜度爲 O(n),由於要遍歷列表,數據量增大幾倍,耗時也增大幾倍。

四、查找一個未排序的列表時間複雜度爲 O(n),由於要遍歷列表;查找排序過的列表時間複雜度爲 O(log n),由於可使用二分查找法,當數據增大 n 倍時,耗時增大 logn 倍(這裏的 log 是以 2 爲底的,每找一次排除一半的可能)。

2)鏈表

鏈表在物理存儲空間是不連續的,但每一個節點要麼知道它的下一個節點是誰,要麼知道它的上一個節點是誰,彷彿就像咱們之間隔着千山萬水,卻心有靈犀一點鏈。像 LinkedList 就是最典型的鏈表結構,經過引用相互連接。

LinkedList 中的每個元素均可以稱之爲節點(Node),每個節點都包含三個項目:其一是元素自己,其二是指向下一個元素的引用地址,其三是指向上一個元素的引用地址。

LinkedList 看起來就像下面這個樣子:

站在巨人的肩膀上學數據結構,不飄也難啊!

  • 第一個節點因爲沒有前一個節點,因此 prev 爲 null;
  • 最後一個節點因爲沒有後一個節點,因此 next 爲 null;
  • 這是一個雙向鏈表,每個節點都由三部分組成,先後節點和值。

相比 ArrayList,LinkedList 有如下優點:

一、LinkedList 容許內存進行動態分配,這就意味着內存分配是由編譯器在運行時完成的,咱們無需在 LinkedList 聲明的時候指定大小。

二、LinkedList 不須要在連續的位置上存儲元素,由於節點能夠經過引用指定下一個節點或者前一個節點。也就是說,LinkedList 在插入和刪除元素的時候代價很低,由於不須要移動其餘元素,只須要更新前一個節點和後一個節點的引用地址便可。

3)棧

棧是一種很是有用的數據結構,它就像一摞盤子,第一個放在最下面,第二個放在第一個上面,第三個放在第二個上面,最後一個放在最上面。棧遵循後進先出的原則,也就是「Last In First Out」(簡稱 LIFO)——最後的一個進的,最早出去。

對於棧這樣一個數據結構來講,它有兩個常見的動做:

  • push,中文釋義有不少種,我我的更喜歡叫它「壓入」,很是形象。當咱們要把一個數據放入棧的頂部,這個動做就叫作 push。
  • pop,一樣的,我我的更喜歡叫它「彈出」,帶有很強烈的動畫效果,有沒有?當咱們要從棧中移除一個數據時,這個動做就叫作 pop。

站在巨人的肩膀上學數據結構,不飄也難啊!

4)隊列

隊列,只容許在隊尾添加數據,隊首移除數據。隊列在 Java 中的出現頻率很是高,有各類不一樣的類來知足不一樣的場景需求。像優先級隊列 PriorityQueue、延時隊列 DelayQueue 等等。隊列遵循的是 First In First Out,縮寫爲 FIFO,也就是先進先出,第一個進入隊列的第一個先出來。

站在巨人的肩膀上學數據結構,不飄也難啊!

非線性數據結構

1) 樹

樹是一種典型的非線性結構,它是由 n(n>0)個有限節點組成的一個具備層次關係的集合。之因此叫「樹」,是由於這種數據結構看起來就像是一個倒掛的樹,只不過根在上,葉在下。樹形數據結構有如下這些特色:

  • 每一個節點都只有有限個子節點或無子節點;
  • 沒有父節點的節點稱爲根節點;
  • 每個非根節點有且只有一個父節點;
  • 除了根節點外,每一個子節點能夠分爲多個不相交的子樹。

下圖展現了樹的一些術語:

站在巨人的肩膀上學數據結構,不飄也難啊!

根節點是第 0 層,它的子節點是第 1 層,子節點的子節點爲第 2 層,以此類推。

  • 深度:對於任意節點 n,n 的深度爲從根到 n 的惟一路徑長,根的深度爲 0。
  • 高度:對於任意節點 n,n 的高度爲從 n 到一片樹葉的最長路徑長,全部樹葉的高度爲 0。

樹又能夠細分爲下面幾種:

一、普通樹

對子節點沒有任何約束。

站在巨人的肩膀上學數據結構,不飄也難啊!

二、二叉樹

每一個節點最多含有兩個子節點的樹。 二叉樹按照不一樣的表現形式又能夠分爲多種。

2.一、普通二叉樹

每一個子節點的父節點不必定有兩個子節點的二叉樹。

2.二、徹底二叉樹

對於一棵二叉樹,假設其深度爲d(d>1)。除了第 d 層外,其它各層的節點數目均已達最大值,且第 d 層全部節點從左向右連續地緊密排列。

2.三、滿二叉樹

一棵每一層的節點數都達到了最大值的二叉樹。有兩種表現形式,第一種,像下圖這樣(每一層都是滿的),知足每一層的節點數都達到了最大值 2。

站在巨人的肩膀上學數據結構,不飄也難啊!

三、二叉查找樹:

英文名叫 Binary Search Tree,即 BST,須要知足如下條件:

  • 任意節點的左子樹不空,左子樹上全部節點的值均小於它的根節點的值;
  • 任意節點的右子樹不空,右子樹上全部節點的值均大於它的根節點的值;
  • 任意節點的左、右子樹也分別爲二叉查找樹。

站在巨人的肩膀上學數據結構,不飄也難啊!

3.一、平衡二叉樹

當且僅當任何節點的兩棵子樹的高度差不大於 1 的二叉樹。由前蘇聯的數學家 Adelse-Velskil 和 Landis 在 1962 年提出的高度平衡的二叉樹,根據科學家的英文名也稱爲 AVL 樹。

平衡二叉樹本質上也是一棵二叉查找樹,不過爲了限制左右子樹的高度差,避免出現傾斜樹等偏向於線性結構演化的狀況,因此對二叉搜索樹中每一個節點的左右子樹做了限制,左右子樹的高度差稱之爲平衡因子,樹中每一個節點的平衡因子絕對值不大於 1。

平衡二叉樹的難點在於,當刪除或者增長節點的狀況下,如何經過左旋或者右旋的方式來保持左右平衡。

紅黑樹是一種常見的平衡二叉樹,節點是紅色或者黑色,經過顏色的約束來維持着二叉樹的平衡:

  • 每一個節點都只能是紅色或者黑色
  • 根節點是黑色
  • 每一個葉節點(NIL 節點,空節點)是黑色的。
  • 若是一個節點是紅色的,則它兩個子節點都是黑色的。也就是說在一條路徑上不能出現相鄰的兩個紅色節點。
  • 從任一節點到其每一個葉子的全部路徑都包含相同數目的黑色節點。

四、B 樹

一種對讀寫操做進行優化的自平衡的二叉查找樹,可以保持數據有序,擁有多於兩個的子樹。

站在巨人的肩膀上學數據結構,不飄也難啊!

五、B+ 樹

B 樹的變體

站在巨人的肩膀上學數據結構,不飄也難啊!

HashMap 裏面的 TreeNode 就用到了紅黑樹,而 B 樹、B+ 樹在數據庫的索引原理裏面有典型的應用。

2)哈希表

哈希表(Hash Table),也叫散列表,是一種能夠經過關鍵碼值(key-value)直接訪問的數據結構,它最大的特色就是能夠快速實現查找、插入和刪除。其中用到的算法叫作哈希,就是把任意長度的輸入,變換成固定長度的輸出,該輸出就是哈希值。像 MD五、SHA1 都用的是哈希算法。

每個 Java 對象都會有一個哈希值,默認狀況就是經過調用本地方法執行哈希算法,計算出對象的內存地址 + 對象的值的關鍵碼值。

數組的最大特色就是查找容易,插入和刪除困難;而鏈表正好相反,查找困難,而插入和刪除容易。哈希表很完美地結合了二者的優勢, Java 的 HashMap 在此基礎上還加入了樹的優勢。

站在巨人的肩膀上學數據結構,不飄也難啊!

哈希表具備較快(常量級)的查詢速度,以及相對較快的增刪速度,因此很適合在海量數據的環境中使用。

對於任意兩個不一樣的數據塊,其哈希值相同的可能性極小,也就是說,對於一個給定的數據塊,找到和它哈希值相同的數據塊極爲困難。再者,對於一個數據塊,哪怕只改動它的一個比特位,其哈希值的改動也會很是的大——這正是 Hash 存在的價值!

儘管可能性極小,但仍然會發生,若是哈希衝突了,Java 的 HashMap 會在數組的同一個位置上增長鏈表,若是鏈表的長度大於 8,將會轉化成紅黑樹進行處理——這就是所謂的拉鍊法(數組+鏈表)。

3)圖

圖是一種複雜的非線性結構,由頂點的有窮非空集合和頂點之間邊的集合組成,一般表示爲:G(V,E),其中,G 表示一個圖,V 視圖 G 中頂點的集合,E 是圖 G 中邊的集合。

站在巨人的肩膀上學數據結構,不飄也難啊!

上圖共有 V0,V1,V2,V3 這 4 個頂點,4 個頂點之間共有 5 條邊。

在線性結構中,數據元素之間知足惟一的線性關係,每一個數據元素(除第一個和最後一個外)均有惟一的「前驅」和「後繼」;

在樹形結構中,數據元素之間有着明顯的層次關係,而且每一個數據元素只與上一層中的一個元素(父節點)及下一層的多個元素(子節點)相關;今日讀者福利:學習筆記+面試真題

而在圖形結構中,節點之間的關係是任意的,圖中任意兩個數據元素之間都有可能相關。

相關文章
相關標籤/搜索