Java基礎教程:常見數據結構簡介

2021-01-08 黑馬程式設計師

數據結構介紹

數據結構 : 數據用什麼樣的方式組合在一起。

常見數據結構

數據存儲的常用結構有:棧、隊列、數組、鍊表和紅黑樹。我們分別來了解一下:

棧:stack,又稱堆棧,它是運算受限的線性表,其限制是僅允許在標的一端進行插入和刪除操作,不允許在其他任何位置進行添加、查找、刪除等操作。

簡單的說:採用該結構的集合,對元素的存取有如下的特點

先進後出(即,存進去的元素,要在後它後面的元素依次取出後,才能取出該元素)。例如,子彈壓進彈夾,先壓進去的子彈在下面,後壓進去的子彈在上面,當開槍時,先彈出上面的子彈,然後才能彈出下面的子彈。棧的入口、出口的都是棧的頂端位置。

這裡兩個名詞需要注意:

壓棧:就是存元素。即,把元素存儲到棧的頂端位置,棧中已有元素依次向棧底方向移動一個位置。彈棧:就是取元素。即,把棧的頂端位置元素取出,棧中已有元素依次向棧頂方向移動一個位置。

隊列

隊列:queue,簡稱隊,它同堆棧一樣,也是一種運算受限的線性表,其限制是僅允許在表的一端進行插入,而在表的另一端進行刪除。

簡單的說,採用該結構的集合,對元素的存取有如下的特點:

先進先出(即,存進去的元素,要在後它前面的元素依次取出後,才能取出該元素)。例如,小火車過山洞,車頭先進去,車尾後進去;車頭先出來,車尾後出來。隊列的入口、出口各佔一側。例如,下圖中的左側為入口,右側為出口。

數組

數組:Array,是有序的元素序列,數組是在內存中開闢一段連續的空間,並在此空間存放元素。就像是一排出租屋,有100個房間,從001到100每個房間都有固定編號,通過編號就可以快速找到租房子的人。

簡單的說,採用該結構的集合,對元素的存取有如下的特點:

查找元素快:通過索引,可以快速訪問指定位置的元素

增刪元素慢指定索引位置增加元素:需要創建一個新數組,將指定新元素存儲在指定索引位置,再把原數組元素根據索引,複製到新數組對應索引的位置。如下圖

指定索引位置刪除元素:需要創建一個新數組,把原數組元素根據索引,複製到新數組對應索引的位置,原數組中指定索引位置元素不複製到新數組中。如下圖

鍊表

鍊表:linked list,由一系列結點node(鍊表中每一個元素稱為結點)組成,結點可以在運行時i動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。我們常說的鍊表結構有單向鍊表與雙向鍊表,那麼這裡給大家介紹的是單向鍊表。

簡單的說,採用該結構的集合,對元素的存取有如下的特點:

多個結點之間,通過地址進行連接。例如,多個人手拉手,每個人使用自己的右手拉住下個人的左手,依次類推,這樣多個人就連在一起了。查找元素慢:想查找某個元素,需要通過連接的節點,依次向後查找指定元素增刪元素快:

樹數據結構,樹是有很多節點組成的

樹基本結構介紹

樹具有的特點:

每一個節點有零個或者多個子節點沒有父節點的節點稱之為根節點,一個樹最多有一個根節點。每一個非根節點有且只有一個父節點

二叉樹

如果樹中的每個節點的子節點的個數不超過2,那麼該樹就是一個二叉樹。

二叉查找樹/二叉排序樹

二叉查找樹的特點:

左子樹上所有的節點的值均小於等於他的根節點的值右子樹上所有的節點值均大於或者等於他的根節點的值每一個子節點最多有兩個子樹

案例演示(20,18,23,22,17,24,19)數據的存儲過程;

增刪改查的性能都很高!!!

遍歷獲取元素的時候可以按照"左中右"的順序進行遍歷;

注意:二叉查找樹存在的問題:會出現"瘸子"的現象,影響查詢效率。

平衡二叉樹

(基於查找二叉樹,但是讓樹不要太高,儘量讓樹的元素均衡分布。這樣綜合性能就高了)

概述

為了避免出現"瘸子"的現象,減少樹的高度,提高我們的搜素效率,又存在一種樹的結構:"平衡二叉樹"

規則:它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹

如下圖所示:

如下圖所示,左圖是一棵平衡二叉樹,根節點10,左右兩子樹的高度差是1,而右圖,雖然根節點左右兩子樹高度差是0,但是右子樹15的左右子樹高度差為2,不符合定義,

所以右圖不是一棵平衡二叉樹。

旋轉

在構建一棵平衡二叉樹的過程中,當有新的節點要插入時,檢查是否因插入後而破壞了樹的平衡,如果是,則需要做旋轉去改變樹的結構。

左旋:

左旋就是將節點的右支往左拉,右子節點變成父節點,並把晉升之後多餘的左子節點出讓給降級節點的右子節點;

右旋:

將節點的左支往右拉,左子節點變成了父節點,並把晉升之後多餘的右子節點出讓給降級節點的左子節點

舉個例子,像上圖是否平衡二叉樹的圖裡面,左圖在沒插入前"19"節點前,該樹還是平衡二叉樹,但是在插入"19"後,導致了"15"的左右子樹失去了"平衡",

所以此時可以將"15"節點進行左旋,讓"15"自身把節點出讓給"17"作為"17"的左樹,使得"17"節點左右子樹平衡,而"15"節點沒有子樹,左右也平衡了。如下圖,

由於在構建平衡二叉樹的時候,當有新節點插入時,都會判斷插入後時候平衡,這說明了插入新節點前,都是平衡的,也即高度差絕對值不會超過1。當新節點插入後,

有可能會有導致樹不平衡,這時候就需要進行調整,而可能出現的情況就有4種,分別稱作左左,左右,右左,右右

左左

左左即為在原來平衡的二叉樹上,在節點的左子樹的左子樹下,有新節點插入,導致節點的左右子樹的高度差為2,如下即為"10"節點的左子樹"7",的左子樹"4",插入了節點"5"或"3"導致失衡。

左左調整其實比較簡單,只需要對節點進行右旋即可,如下圖,對節點"10"進行右旋,

左右

左右即為在原來平衡的二叉樹上,在節點的左子樹的右子樹下,有新節點插入,導致節點的左右子樹的高度差為2,如上即為"11"節點的左子樹"7",的右子樹"9",

插入了節點"10"或"8"導致失衡。

左右的調整就不能像左左一樣,進行一次旋轉就完成調整。我們不妨先試著讓左右像左左一樣對"11"節點進行右旋,結果圖如下,右圖的二叉樹依然不平衡,而右圖就是接下來要

講的右左,即左右跟右左互為鏡像,左左跟右右也互為鏡像。

左右這種情況,進行一次旋轉是不能滿足我們的條件的,正確的調整方式是,將左右進行第一次旋轉,將左右先調整成左左,然後再對左左進行調整,從而使得二叉樹平衡。

即先對上圖的節點"7"進行左旋,使得二叉樹變成了左左,之後再對"11"節點進行右旋,此時二叉樹就調整完成,如下圖:

右左

右左

右左即為在原來平衡的二叉樹上,在節點的右子樹的左子樹下,有新節點插入,導致節點的左右子樹的高度差為2,如上即為"11"節點的右子樹"15",的左子樹"13",

插入了節點"12"或"14"導致失衡。

前面也說了,右左跟左右其實互為鏡像,所以調整過程就反過來,先對節點"15"進行右旋,使得二叉樹變成右右,之後再對"11"節點進行左旋,此時二叉樹就調整完成,如下圖:

右右

右右即為在原來平衡的二叉樹上,在節點的右子樹的右子樹下,有新節點插入,導致節點的左右子樹的高度差為2,如下即為"11"節點的右子樹"13",的左子樹"15",插入了節點

"14"或"19"導致失衡。

右右只需對節點進行一次左旋即可調整平衡,如下圖,對"11"節點進行左旋。

紅黑樹

就是平衡的二叉查找樹!!

概述

紅黑樹是一種自平衡的二叉查找樹,是計算機科學中用到的一種數據結構,它是在1972年由Rudolf Bayer發明的,當時被稱之為平衡二叉B樹,後來,在1978年被

Leoj.Guibas和Robert Sedgewick修改為如今的"紅黑樹"。它是一種特殊的二叉查找樹,紅黑樹的每一個節點上都有存儲位表示節點的顏色,可以是紅或者黑;

紅黑樹不是高度平衡的,它的平衡是通過"紅黑樹的特性"進行實現的;

紅黑樹的特性:

每一個節點或是紅色的,或者是黑色的。根節點必須是黑色每個葉節點(Nil)是黑色的;(如果一個節點沒有子節點或者父節點,則該節點相應的指針屬性值為Nil,這些Nil視為葉節點)如果某一個節點是紅色,那麼它的子節點必須是黑色(不能出現兩個紅色節點相連的情況)對每一個節點,從該節點到其所有後代葉節點的簡單路徑上,均包含相同數目的黑色節點;

如下圖所示就是一個

在進行元素插入的時候,和之前一樣; 每一次插入完畢以後,使用黑色規則進行校驗,如果不滿足紅黑規則,就需要通過變色,左旋和右旋來調整樹,使其滿足紅黑規則;

相關焦點

  • Java基礎教程:java反射機制教程
    這時候java語言在設計的時候為我們提供了一個機制,就是反射機制,他能夠很方便的去解決我們的問題。 二、深入分析java反射機制 1、獲取Class類 在java中萬事萬物皆對象,Useruser=newUser()一行代碼我們知道了user是User類的實例對象,通過Studentstu=newStudent()我們知道了
  • 數據結構java面試題及答案
    數組是最常用的基礎數據結構,它將元素保存在連續的內存中。它也是面試最喜歡的問題之一,在代碼面試中你會經常聽到很多關於數組的問題,例如,數組的反轉、數組的排序或者查找數組中的一個元素。數組結構的一個關鍵優點是在知道索引的情況能夠以O(1)的複雜度找到一個元素。但是增加或者刪除一個元素是很慢的,因為一旦創建了一個數組,你就不能改變它的大小了。
  • java基礎教程:Collection集合,Collection 常用API
    集合:集合是java中提供的一種容器,可以用來存儲多個數據。集合和數組既然都是容器,它們有什麼區別呢?數組的長度是固定的。集合的長度是可變的。數組中存儲的是同一類型的元素,可以存儲任意類型數據。集合存儲的都是引用數據類型。如果想存儲基本類型數據需要存儲對應的包裝類型。
  • Android被指抄襲Java代碼引爭議
    針對此事,《Android基礎教程》的作者Ed Burnette在ZDNet發表博文指出,關於Florian Mueller發布的關於Android抄襲Java代碼的文章裡,存在兩個疑問。(轉自谷奧)首先是第一組的7個抄襲的java文件(PolicyNodeImpl.java, AclEntryImpl.java, AclImpl.java, GroupImpl.java, OwnerImpl.java, PermissionImpl.java 和 PrincipalImpl.java)都屬於原始碼裡的測試分支。任何程式設計師都不會將測試代碼放到最終發布的產品裡。
  • Java常見內存溢出異常分析
    at java.util.Arrays.copyof(Arrays.java:3181)   堆內存溢出的時候,虛擬機會拋出java.lang.OutOfMemoryError:java heap space,出現此種情況的時候,我們需要根據內存溢出的時候產生的dump文件來具體分析(需要增加-XX:+HeapDumpOnOutOfMemoryErrorjvm啟動參數)。
  • Java 編程技巧之數據結構
    筆者從數據結構的角度,整理了一些 Java 編程技巧,以供大家學習參考。使用HashSet判斷主鍵是否存在HashSet 實現 Set 接口,由哈希表(實際上是 HashMap )實現,但不保證 set 的迭代順序,並允許使用 null 元素。
  • Java數據結構的線性結構和非線性結構,這篇足夠了
    數據結構與算法,可以說是程式設計師的靈魂。大家在找工作面試的時候,尤其是大網際網路公司面試的時候,數據結構與算法必問,想要學好數據結構,首先你要高效而愉快地學習,作為優秀的程式設計師它可以在海量數據計算的時候,依然保持高速地計算。
  • Java基礎學習:java中的基本數據類型
    二、案例用法 1、類型轉換 自動轉換:範圍小的數據類型可以自動轉換成範圍大的數據類型 強制轉換:把一種數據類型轉換為另外一種數據類型。 類型提升:表達式運算中有不同的數據類型,類型會自動向範圍大的提升。
  • Java程式設計師必備基礎:Java代碼是怎麼運行的?
    虛擬機把描述類的數據從 Class 文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的 Java 類型,這就是虛擬機的類加載機制。 將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構。
  • java第三章循環結構和random知識點總結
    示例代碼:public class ForTest02 {public static void main(String[] args) {//求和的最終結果必須保存起來,需要定義一個變量,用於保存求和的結果,初始值為0int sum = 0;//從1開始到5結束的數據,使用循環結構完成for(int i
  • 我們到底該如何學習《數據結構與算法》
    前言:我們到底該不該學習算法與數據結構?1、真的應該學習這個問題本身就不是個問題,所有人都在強調數據結構與算法比較重要,但是好像平時也沒用到,無法直觀的去感受它的重要性,於是把學習重心放在了常見的哪些框架身上,似乎只要熟悉了哪些框架的API,編程就會所向披靡。
  • 學java可以做什麼?大數據前景和就業方向又是什麼樣的呢?
    學java可以做什麼?(1) Java可以用來做網站:很多大型網站都是用JSP寫的,JSP全名java server pages,這是一種動態網頁技術,比如我們熟悉的B站,很多政府網站都是用這個寫的所以想學習java的同學還可以負責網站方面的製作,這方面的崗位也比較多。
  • JAVA必須掌握的數據結構和算法
    常見的數據結構鍊表LinkedHashSet LinkedList 底層數據結構由鍊表和哈希表組成。數據的添加和刪除都較為方便,就是訪問比較耗費時間。數組ArrayList 訪問數據十分簡單,而添加和刪除數據比較耗工夫堆堆是一種圖的樹形結構,被用於實現「優先隊列",優先隊列是一種數據結構,可以自由添加數據,但取出數據時要從最小值開始按順序取出
  • 跟我學java編程—認識java語言的字符類型
    前面兩個小節討論了用於存儲數值的數據類型。另外還經常會遇到需要存儲並操縱字符型數據的情況。例如:計算數值表達式時,需要存儲運算符,這時需要一種可以存儲單個字符數據的數據類型。Java語言提供了一種char數據類型,可以滿足存儲單個字符的需要。
  • 跟我學java編程—深入理解for語句的嵌套循環
    本節介紹for循環結構,for循環也可以嵌套。不僅如此,for循環還可以和其它的循環結構混合嵌套。嵌套循環時,必須將被嵌套的循環語句完整地包含在外層循環的循環體內,下面給出一些循環嵌套的示例。示例1:用「*」輸出一個菱形圖案,圖案如下: 在D盤Java目錄下,新建「ForSample1.java」文件。用記事本打開「ForSample1.java」文件,輸入以下代碼:代碼結構分析程序功能主要是演示for嵌套循環的使用方法。
  • 跟我學java編程—認識java的整數類型
    Java語言中,基本的整型數據類型有byte、short、int、long四種類型,用於需要不同存儲空間的數據使用。整型有正整數和負整數之分,在Java語言中,規定整型的最高位為符號位,最高位為「0」表示正數,最高位為「1」表示負數,其它位表示數值。因此整型類型的數據能夠表示的最小值為:-2n-1 —2n-1-1(n為該類型所佔存儲空間的二進位位數)。
  • 尚學堂知識整理:Java double數據類型
    double數據類型使用64位來存儲浮點數。double值也稱為雙精度浮點數。它可以表示一個最小為4.9 x 10^-324,最大為1.7 x 10^308的數字。它可以是正的或負的。所有實數被稱為double字面量。
  • 三極體常見分類簡介
    打開APP 三極體常見分類簡介 佚名 發表於 2016-12-21 10:44:57   三極體,全稱應為半導體三極體,也稱雙極型電晶體
  • 一篇文章讓你了解二分搜索樹的數據結構的實現過程(Java 實現)
    樹結構簡介在線性數據結構中,數據都是排成一排存放的;而樹結構則是非線性的,存儲在其中的數據是按分支關係組織起來的結構,就像自然界中的樹那樣。對於這種組織結構,日常生活中是非常常見的,比如電腦磁碟中的文件夾、公司中的人員組織結構、家族的族譜等等,如以下幾圖所示:除了組織數據,使用樹結構存儲數據時,在某些情況下,處理數據是十分高效的。
  • 面試頻率最高的簡單問題——Java類的三大基本特徵
    學習過Java的程式設計師都知道,java類有三大特徵——封裝、繼承和多態。下面的文章給大家詳細的介紹一下java的這三大特性。封裝封裝是將描述某類事物的數據與處理這些數據的函數封裝在一起,形成一個有機整體,稱為類。類所具有的的封裝性可使程序模塊具有良好的獨立性與可維護性。