數(shù)據(jù)結(jié)構(gòu)

算法 + 數(shù)據(jù)結(jié)構(gòu) = 程序

一、簡述

1??數(shù)據(jù)結(jié)構(gòu)
數(shù)據(jù)結(jié)構(gòu)是指相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合,是計算機存儲灿里、組織數(shù)據(jù)的方式。再簡單描述一下:數(shù)據(jù)結(jié)構(gòu)就是描述對象間邏輯關(guān)系的學科程腹。8 種常用數(shù)據(jù)結(jié)構(gòu):數(shù)組匣吊、鏈表、棧寸潦、隊列缀去、圖、甸祭、前綴樹缕碎、哈希表

2??數(shù)據(jù)存儲結(jié)構(gòu)
簡單的講就是數(shù)據(jù)在計算機中的存儲方式池户。常用的數(shù)據(jù)存儲方式有兩種:順序存儲咏雌,非順序存儲凡怎。順序存儲就是把數(shù)據(jù)存儲在一塊連續(xù)的存儲介質(zhì)(硬盤或內(nèi)存等)中,反之就是非順序存儲赊抖。Java 中的數(shù)組就是典型的順序存儲统倒,鏈表就是非順序存儲。數(shù)組存儲數(shù)據(jù)時會開辟出一塊連續(xù)內(nèi)存氛雪,按順序存儲房匆。鏈表則是只需要知道下一個節(jié)點存儲的位置,就能把所有的數(shù)據(jù)連起來了报亩。所以單向鏈表的最后一個節(jié)點是指向 Null 的浴鸿。

二、數(shù)組(Array)

數(shù)組是數(shù)據(jù)結(jié)構(gòu)中最簡單弦追,也是最常用的結(jié)構(gòu)岳链,很多編程語言都內(nèi)置數(shù)組。其他數(shù)據(jù)結(jié)構(gòu)劲件,比如棧和隊列都是由數(shù)組衍生出來的掸哑。下圖展示了 1 個數(shù)組,它有 4 個元素零远。每一個數(shù)組元素的位置由數(shù)字編號苗分,稱為下標或者索引(index)。大多數(shù)編程語言的數(shù)組第一個元素的下標是 0牵辣。

根據(jù)維度區(qū)分摔癣,有兩種不同的數(shù)組:

1??一維數(shù)組(如上圖所示)
2??多維數(shù)組(數(shù)組的元素為數(shù)組)

在 Java 中當創(chuàng)建數(shù)組時會在內(nèi)存中劃分出一塊連續(xù)的內(nèi)存,然后當有數(shù)據(jù)進入的時候會將數(shù)據(jù)按順序的存儲在這塊連續(xù)的內(nèi)存中服猪。當需要讀取數(shù)組中的數(shù)據(jù)時供填,需要提供數(shù)組中的索引,然后數(shù)組根據(jù)索引將內(nèi)存中的數(shù)據(jù)取出來罢猪,返回給讀取程序近她。在Java中并不是所有的數(shù)據(jù)都能存儲到數(shù)組中,只有相同類型的數(shù)據(jù)才可以一起存儲到數(shù)組中膳帕。

所有的數(shù)據(jù)結(jié)構(gòu)都支持幾個基本操作:讀取Get粘捎、插入Insert、刪除Delete危彩。

因為數(shù)組在存儲數(shù)據(jù)時是按順序存儲的攒磨,存儲數(shù)據(jù)的內(nèi)存也是連續(xù)的,所以它的特點就是尋址讀取數(shù)據(jù)比較容易汤徽,插入和刪除比較困難娩缰。在讀取數(shù)據(jù)時,只需要告訴數(shù)組要從哪個位置(索引)取數(shù)據(jù)就可以了谒府,數(shù)組會直接把想要的位置的數(shù)據(jù)取出來拼坎。插入和刪除比較困難是因為這些存儲數(shù)據(jù)的內(nèi)存是連續(xù)的浮毯,要插入和刪除就需要變更整個數(shù)組中的數(shù)據(jù)的位置。舉個例子:一個數(shù)組中編號0->1->2->3->4這五個內(nèi)存地址中都存了數(shù)組的數(shù)據(jù)泰鸡,現(xiàn)在需要往4中插入一個數(shù)據(jù)债蓝,那就代表著從4開始,后面的所有內(nèi)存中的數(shù)據(jù)都要往后移一個位置盛龄,相當耗時饰迹。

三、鏈表(Linked List) 線性結(jié)構(gòu)

鏈表與數(shù)組看起來非常像余舶,但是內(nèi)存分配方式啊鸭、內(nèi)部結(jié)構(gòu)和插入刪除操作方式都不一樣。鏈表是一系列節(jié)點組成的鏈欧芽,每一個節(jié)點保存了數(shù)據(jù)以及指向下一個節(jié)點的指針莉掂。鏈表頭指針指向第一個節(jié)點葛圃,如果鏈表為空千扔,則頭指針為空或者為 null。鏈表可以用來實現(xiàn)文件系統(tǒng)库正、哈希表和鄰接表曲楚。

在 Java 中創(chuàng)建鏈表的過程和創(chuàng)建數(shù)組的過程不同,不會先劃出一塊連續(xù)的內(nèi)存褥符。因為鏈表中的數(shù)據(jù)并不是連續(xù)的龙誊,鏈表在存儲數(shù)據(jù)的內(nèi)存中有兩塊區(qū)域,一塊區(qū)域用來存儲數(shù)據(jù)喷楣,一塊區(qū)域用來記錄下一個數(shù)據(jù)保存在哪里(指向下一個數(shù)據(jù)的指針)趟大。當有數(shù)據(jù)進入鏈表時候,會根據(jù)指針找到下一個存儲數(shù)據(jù)的位置铣焊,然后把數(shù)據(jù)保存起來逊朽,然后再指向下一個存儲數(shù)據(jù)的位置。這樣鏈表就把一些碎片空間利用起來了曲伊,雖然鏈表是線性表叽讳,但是并不會按線性的順序存儲數(shù)據(jù)。

由于鏈表是以這種方式保存數(shù)據(jù)坟募,所以鏈表在插入和刪除時比較容易岛蚤,讀取數(shù)據(jù)時比較麻煩。舉個例子:一個鏈表中0->1->2->3->4這五個內(nèi)存地址中都存了數(shù)據(jù)懈糯,現(xiàn)在需要往2中插入一條數(shù)據(jù)涤妒,那么只需要更改1號和2號中記錄下一個數(shù)據(jù)的位置就行了,對其他數(shù)據(jù)沒有影響赚哗。刪除一條數(shù)據(jù)與插入類似她紫,很高效铁坎。但是如果是想要在鏈表其中取出一條數(shù)據(jù),就需要從0號開始一個一個的找犁苏,直到找到想要的那條數(shù)據(jù)為止硬萍。

鏈表中插入數(shù)據(jù)
鏈表中刪除數(shù)據(jù)

鏈表分為 2 種:

  • 單向鏈表
  • 雙向鏈表

鏈表的基本操作

  • InsertAtEnd — 在鏈表結(jié)尾插入元素
  • InsertAtHead — 在鏈表開頭插入元素
  • Delete — 刪除鏈表的指定元素
  • DeleteAtHead — 刪除鏈表第一個元素
  • Search — 在鏈表中查詢指定元素
  • isEmpty — 查詢鏈表是否為空

四、棧(stack) LIFO

棧是一種先進后出的數(shù)據(jù)結(jié)構(gòu)围详,數(shù)組和鏈表都可以生成棧朴乖。當數(shù)據(jù)進入到棧時會按照規(guī)則壓入到棧的底部,再次進入的數(shù)據(jù)會壓在前一次的數(shù)據(jù)上面助赞,以此類推买羞。在取出棧中的數(shù)據(jù)的時候會先取出最上面的數(shù)據(jù),所以是先進后出雹食。


由于數(shù)組和鏈表都可以組成棧畜普,所以操作特點就需要看棧是由數(shù)組還是鏈表生成的了,然后就會繼承相應(yīng)的操作特點群叶。最常見的操作撤回(Ctrl+Z)吃挑,就是利用棧實現(xiàn)的。原理:把之前的應(yīng)用狀態(tài)(限制個數(shù))保存到內(nèi)存中街立,最近的狀態(tài)放到第一個舶衬。

棧的基本操作

  • Push — 在棧的最上方插入元素
  • Pop — 返回棧最上方的元素,并將其刪除
  • isEmpty — 查詢棧是否為空
  • Top — 返回棧最上方的元素赎离,并不刪除

五逛犹、隊列(Queue) FIFO

隊列與棧類似,都是采用線性結(jié)構(gòu)存儲數(shù)據(jù)梁剔。它們的區(qū)別在于虽画,棧采用 LIFO 方式,而隊列采用先進先出荣病,即 FIFO(First in First Out)码撰。數(shù)組和鏈表也都可以生成隊列。當數(shù)據(jù)進入到隊列中時也是先進入的在下面后進入的在上面众雷,但是出隊列的時候是先從下面出灸拍,然后才是上面的數(shù)據(jù)出,最晚進入的隊列的砾省,最后出鸡岗。

舉個簡單的例子:可以把棧和隊列看成是兩根管子,這兩根管子是用來存儲數(shù)據(jù)的编兄,有可能是數(shù)組生成的也有可能是鏈表生成的轩性,棧的這根管子有一頭是封死的,所以像這個管子放數(shù)據(jù)只能從一個口進狠鸳,拿出數(shù)據(jù)的時候也只能從這一個口拿出來揣苏。而隊列這根管子呢兩個口都是敞開的悯嗓,一個口負責進數(shù)據(jù),另一個口負責出數(shù)據(jù)卸察,所以從一進口先進去的數(shù)據(jù)脯厨,在出口處會先被拿出來。

隊列的基本操作

  • Enqueue — 在隊列末尾插入元素
  • Dequeue — 將隊列第一個元素刪除
  • isEmpty — 查詢隊列是否為空
  • Top — 返回隊列的第一個元素

六坑质、圖(graph)

圖由多個節(jié)點(vertex)構(gòu)成合武,節(jié)點之間闊以互相連接組成一個網(wǎng)絡(luò)。(x, y)表示一條邊(edge)涡扼,它表示節(jié)點 x 與 y 相連稼跳。邊可能會有權(quán)值(weight/cost)。

圖分為兩種:

  • 無向圖
  • 有向圖

在編程語言中吃沪,圖有可能有以下兩種形式表示:

  • 鄰接矩陣(Adjacency Matrix)
  • 鄰接表(Adjacency List)

遍歷圖有兩周算法

  • 廣度優(yōu)先搜索(Breadth First Search)
  • 深度優(yōu)先搜索(Depth First Search)

七汤善、樹(Tree)

樹是一個分層的數(shù)據(jù)結(jié)構(gòu),由節(jié)點和連接節(jié)點的邊組成票彪。樹是一種特殊的圖红淡,它與圖最大的區(qū)別是沒有循環(huán)。樹被廣泛應(yīng)用在人工智能和一些復(fù)雜算法中抹镊,用來提供高效的存儲結(jié)構(gòu)锉屈。下圖是一個簡單的樹以及與樹相關(guān)的術(shù)語:

樹有很多分類:

  • N 叉樹(N-ary Tree)
  • 平衡樹(Balanced Tree)
  • 二叉樹(Binary Tree)
  • 二叉查找樹(Binary Search Tree)
  • 平衡二叉樹(AVL Tree)
  • 紅黑樹(Red Black Tree)
  • 2-3 樹(2–3 Tree)

其中荤傲,二叉樹和二叉查找樹是最常用的樹垮耳。

八、前綴樹

前綴樹(Prefix Trees 或者 Trie)與樹類似遂黍,用于處理字符串相關(guān)的問題時非常高效终佛。它可以實現(xiàn)快速檢索,常用于字典中的單詞查詢雾家,搜索引擎的自動補全甚至 IP 路由铃彰。下圖展示了“top”, “thus”和“their”三個單詞在前綴樹中如何存儲的:

單詞是按照字母從上往下存儲,“p”, “s”和“r”節(jié)點分別表示“top”, “thus”和“their”的單詞結(jié)尾芯咧。

九牙捉、哈希表(Hash)

哈希將某個對象變換為唯一標識符,該標識符通常用一個短的隨機字母和數(shù)字組成的字符串來代表敬飒。哈闲安可以用來實現(xiàn)各種數(shù)據(jù)結(jié)構(gòu),其中最常用的就是哈希表(hash table)无拗。哈希表通常由數(shù)組實現(xiàn)带到。哈希表的性能取決于 3 個指標:

  • 哈希函數(shù)
  • 哈希表的大小
  • 哈希沖突處理方式

下圖展示了有數(shù)組實現(xiàn)的哈希表,數(shù)組的下標即為哈希值英染,由哈希函數(shù)計算揽惹,作為哈希表的鍵(key)被饿,而數(shù)組中保存的數(shù)據(jù)即為值(value):
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搪搏,隨后出現(xiàn)的幾起案子狭握,更是在濱河造成了極大的恐慌,老刑警劉巖疯溺,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哥牍,死亡現(xiàn)場離奇詭異,居然都是意外死亡喝检,警方通過查閱死者的電腦和手機嗅辣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挠说,“玉大人澡谭,你說我怎么就攤上這事∷鸺螅” “怎么了蛙奖?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長杆兵。 經(jīng)常有香客問我雁仲,道長,這世上最難降的妖魔是什么琐脏? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任攒砖,我火速辦了婚禮,結(jié)果婚禮上日裙,老公的妹妹穿的比我還像新娘吹艇。我一直安慰自己,他們只是感情好昂拂,可當我...
    茶點故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布受神。 她就那樣靜靜地躺著,像睡著了一般格侯。 火紅的嫁衣襯著肌膚如雪鼻听。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天联四,我揣著相機與錄音撑碴,去河邊找鬼。 笑死碎连,一個胖子當著我的面吹牛灰羽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼廉嚼,長吁一口氣:“原來是場噩夢啊……” “哼玫镐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起怠噪,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤恐似,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后傍念,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矫夷,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年憋槐,在試婚紗的時候發(fā)現(xiàn)自己被綠了双藕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡阳仔,死狀恐怖忧陪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情近范,我是刑警寧澤嘶摊,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布,位于F島的核電站评矩,受9級特大地震影響叶堆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜斥杜,卻給世界環(huán)境...
    茶點故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一虱颗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧果录,春花似錦上枕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棋恼。三九已至返弹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間爪飘,已是汗流浹背义起。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留师崎,地道東北人默终。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親齐蔽。 傳聞我的和親對象是個殘疾皇子两疚,可洞房花燭夜當晚...
    茶點故事閱讀 43,576評論 2 349