2、常見(jiàn)的數(shù)據(jù)結(jié)構(gòu)2.1 線性表數(shù)據(jù)結(jié)構(gòu)(data structure)是計(jì)算機(jī)存儲(chǔ)、組織數(shù)據(jù)的方式。是指相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合,即帶“結(jié)構(gòu)”的數(shù)據(jù)元素的集合?!敖Y(jié)構(gòu)”就是指數(shù)據(jù)元素之間存在的關(guān)系,分為邏輯結(jié)構(gòu)和存儲(chǔ)結(jié)構(gòu)。 我們討論的大多是邏輯結(jié)構(gòu)
數(shù)據(jù)邏輯結(jié)構(gòu)
指反映數(shù)據(jù)元素之間的邏輯關(guān)系的數(shù)據(jù)結(jié)構(gòu),其中的邏輯關(guān)系是指數(shù)據(jù)元素之間的前后間關(guān)系,而與他們?cè)谟?jì)算機(jī)中的存儲(chǔ)位置無(wú)關(guān)。邏輯結(jié)構(gòu)包括:
1.集合:數(shù)據(jù)結(jié)構(gòu)中的元素之間除了“同屬一個(gè)集合” 的相互關(guān)系外,別無(wú)其他關(guān)系;
2.線性結(jié)構(gòu):數(shù)據(jù)結(jié)構(gòu)中的元素存在一對(duì)一的相互關(guān)系;
3.樹(shù)形結(jié)構(gòu):數(shù)據(jù)結(jié)構(gòu)中的元素存在一對(duì)多的相互關(guān)系;
4.圖形結(jié)構(gòu):數(shù)據(jù)結(jié)構(gòu)中的元素存在多對(duì)多的相互關(guān)系。
數(shù)據(jù)物理結(jié)構(gòu)
數(shù)據(jù)的物理結(jié)構(gòu)是數(shù)據(jù)結(jié)構(gòu)在計(jì)算機(jī)中的表示(又稱映像),它包括數(shù)據(jù)元素的機(jī)內(nèi)表示和關(guān)系的機(jī)內(nèi)表示。由于具體實(shí)現(xiàn)的方法有順序、鏈接、索引、散列等多種,所以,一種數(shù)據(jù)結(jié)構(gòu)可表示成一種或多種存儲(chǔ)結(jié)構(gòu)。
數(shù)據(jù)元素的機(jī)內(nèi)表示(映像方法): 用二進(jìn)制位(bit)的位串表示數(shù)據(jù)元素。通常稱這種位串為節(jié)點(diǎn)(node)。當(dāng)數(shù)據(jù)元素有若干個(gè)數(shù)據(jù)項(xiàng)組成時(shí),位串中與各個(gè)數(shù)據(jù)項(xiàng)對(duì)應(yīng)的子位串稱為數(shù)據(jù)域(data field)。因此,節(jié)點(diǎn)是數(shù)據(jù)元素的機(jī)內(nèi)表示(或機(jī)內(nèi)映像)。
關(guān)系的機(jī)內(nèi)表示(映像方法):數(shù)據(jù)元素之間的關(guān)系的機(jī)內(nèi)表示可以分為順序映像和非順序映像,常用兩種存儲(chǔ)結(jié)構(gòu):順序存儲(chǔ)結(jié)構(gòu)和鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。順序映像借助元素在存儲(chǔ)器中的相對(duì)位置來(lái)表示數(shù)據(jù)元素之間的邏輯關(guān)系。非順序映像借助指示元素存儲(chǔ)位置的指針(pointer)來(lái)表示數(shù)據(jù)元素之間的邏輯關(guān)系。
數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)
數(shù)據(jù)的邏輯結(jié)構(gòu)在計(jì)算機(jī)存儲(chǔ)空間中的存放形式稱為數(shù)據(jù)的物理結(jié)構(gòu)(也稱為存儲(chǔ)結(jié)構(gòu))。一般來(lái)說(shuō),一種數(shù)據(jù)結(jié)構(gòu)的邏輯結(jié)構(gòu)根據(jù)需要可以表示成多種存儲(chǔ)結(jié)構(gòu),常用的存儲(chǔ)結(jié)構(gòu)有順序存儲(chǔ)、鏈?zhǔn)酱鎯?chǔ)、索引存儲(chǔ)和哈希存儲(chǔ)等。
數(shù)據(jù)的順序存儲(chǔ)結(jié)構(gòu)的特點(diǎn)是:借助元素在存儲(chǔ)器中的相對(duì)位置來(lái)表示數(shù)據(jù)元素之間的邏輯關(guān)系;非順序存儲(chǔ)的特點(diǎn)是:借助指示元素存儲(chǔ)地址的指針表示數(shù)據(jù)元素之間的邏輯關(guān)系。
線性表(Linear List)就是數(shù)據(jù)排成像一條線一樣的結(jié)構(gòu),數(shù)據(jù)只有前后兩個(gè)方向
2.1.1 數(shù)組概念
數(shù)組(Array)是有限個(gè)相同類型的變量所組成的有序集合,數(shù)組中的每一個(gè)變量被稱為元素。數(shù)組是
最為簡(jiǎn)單、最為常用的數(shù)據(jù)結(jié)構(gòu)。
數(shù)組下標(biāo)從零開(kāi)始(Why)
存儲(chǔ)原理
數(shù)組用一組連續(xù)的內(nèi)存空間來(lái)存儲(chǔ)一組具有相同類型的數(shù)據(jù)
時(shí)間復(fù)雜度
讀取和更新都是隨機(jī)訪問(wèn),所以是O(1)
插入數(shù)組擴(kuò)容的時(shí)間復(fù)雜度是O(n),插入并移動(dòng)元素的時(shí)間復(fù)雜度也是O(n),綜合起來(lái)插入操作的時(shí)間
復(fù)雜度是O(n)。
刪除操作,只涉及元素的移動(dòng),時(shí)間復(fù)雜度也是O(n)
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
數(shù)組擁有非常高效的隨機(jī)訪問(wèn)能力,只要給出下標(biāo),就可以用常量時(shí)間找到對(duì)應(yīng)元素
缺點(diǎn):
插入和刪除元素方面。由于數(shù)組元素連續(xù)緊密地存儲(chǔ)在內(nèi)存中,插入、刪除元素都會(huì)導(dǎo)致大量元素被迫
移動(dòng),影響效率。 (ArrayList LinkedList )
申請(qǐng)的空間必須是連續(xù)的,也就是說(shuō)即使有空間也可能因?yàn)闆](méi)有足夠的連續(xù)空間而創(chuàng)建失敗
如果超出范圍,需要重新申請(qǐng)內(nèi)存進(jìn)行存儲(chǔ),原空間就浪費(fèi)了
應(yīng)用
數(shù)組是基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),應(yīng)用太廣泛了,ArrayList、Redis、消息隊(duì)列等等。
概念
鏈表(linked list)是一種在物理上非連續(xù)、非順序的數(shù)據(jù)結(jié)構(gòu),由若干節(jié)點(diǎn)(node)所組成。
鏈表中數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表中的指針鏈接次序?qū)崿F(xiàn)的。鏈表由一系列結(jié)點(diǎn)(鏈表中每一個(gè)元
素稱為結(jié)點(diǎn))組成,結(jié)點(diǎn)可以在運(yùn)行時(shí)動(dòng)態(tài)生成。每個(gè)結(jié)點(diǎn)包括兩個(gè)部分:一個(gè)是存儲(chǔ)數(shù)據(jù)元素的數(shù)據(jù)
域,另一個(gè)是存儲(chǔ)下一個(gè)結(jié)點(diǎn)地址的指針域。(百度百科)
常見(jiàn)的鏈表包括:?jiǎn)捂湵怼㈦p向鏈表、循環(huán)鏈表
存儲(chǔ)原理
數(shù)組在內(nèi)存中的存儲(chǔ)方式是順序存儲(chǔ)(連續(xù)存儲(chǔ)),鏈表在內(nèi)存中的存儲(chǔ)方式則是隨機(jī)存儲(chǔ)(鏈?zhǔn)酱?br />儲(chǔ))。
鏈表的每一個(gè)節(jié)點(diǎn)分布在內(nèi)存的不同位置,依靠next指針關(guān)聯(lián)起來(lái)。這樣可以靈活有效地利用零散的碎
片空間。
時(shí)間復(fù)雜度
查找節(jié)點(diǎn) : O(n)
插入節(jié)點(diǎn):O(1)
更新節(jié)點(diǎn):O(1)
刪除節(jié)點(diǎn):O(1)
優(yōu)缺點(diǎn)
優(yōu)勢(shì)
插入、刪除、更新效率高
省空間
劣勢(shì)
查詢效率較低,不能隨機(jī)訪問(wèn)
應(yīng)用
鏈表的應(yīng)用也非常廣泛,比如樹(shù)、圖、Redis的列表、LRU算法實(shí)現(xiàn)、消息隊(duì)列等
概念
棧(stack)是一種線性數(shù)據(jù)結(jié)構(gòu),棧中的元素只能先入后出(First In Last Out,簡(jiǎn)稱FILO)。
最早進(jìn)入的元素存放的位置叫作棧底(bottom),最后進(jìn)入的元素存放的位置叫作棧頂 (top)。
存儲(chǔ)原理
棧既可以用數(shù)組來(lái)實(shí)現(xiàn),也可以用鏈表來(lái)實(shí)現(xiàn)
時(shí)間復(fù)雜度
入棧和出棧的時(shí)間復(fù)雜度都是O(1)
支持動(dòng)態(tài)擴(kuò)容的順序棧
當(dāng)數(shù)組空間不夠時(shí),我們就重新申請(qǐng)一塊更大的內(nèi)存,將原來(lái)數(shù)組中數(shù)據(jù)統(tǒng)統(tǒng)拷貝過(guò)去。這樣就實(shí)現(xiàn)了
一個(gè)支持動(dòng)態(tài)擴(kuò)容的數(shù)組,通過(guò)前面學(xué)過(guò)的知識(shí),可以得知入棧的時(shí)間復(fù)雜度是O(n)
應(yīng)用
函數(shù)調(diào)用
每進(jìn)入一個(gè)函數(shù),就會(huì)將臨時(shí)變量作為一個(gè)棧入棧,當(dāng)被調(diào)用函數(shù)執(zhí)行完成,返回之后,將這個(gè)函
數(shù)對(duì)應(yīng)的棧幀出棧
瀏覽器的后退功能
我們使用兩個(gè)棧,X 和 Y,我們把首次瀏覽的頁(yè)面依次壓入棧 X,當(dāng)點(diǎn)擊后退按鈕時(shí),再依次從棧
X 中出棧,并將出棧的數(shù)據(jù)依次放入棧 Y。當(dāng)我們點(diǎn)擊前進(jìn)按鈕時(shí),我們依次從棧 Y 中取出數(shù)據(jù),
放入棧 X 中。當(dāng)棧 X 中沒(méi)有數(shù)據(jù)時(shí),那就說(shuō)明沒(méi)有頁(yè)面可以繼續(xù)后退瀏覽了。當(dāng)棧 Y 中沒(méi)有數(shù)
據(jù),那就說(shuō)明沒(méi)有頁(yè)面可以點(diǎn)擊前進(jìn)按鈕瀏覽了
概念
隊(duì)列(queue)是一種線性數(shù)據(jù)結(jié)構(gòu),隊(duì)列中的元素只能先入先出(First In First Out,簡(jiǎn)稱 FIFO)。
隊(duì)列的出口端叫作隊(duì)頭(front),隊(duì)列的入口端叫作隊(duì)尾(rear)。
存儲(chǔ)原理
隊(duì)列這種數(shù)據(jù)結(jié)構(gòu)既可以用數(shù)組來(lái)實(shí)現(xiàn),也可以用鏈表來(lái)實(shí)現(xiàn)
用數(shù)組實(shí)現(xiàn)時(shí),為了入隊(duì)操作的方便,把隊(duì)尾位置規(guī)定為最后入隊(duì)元素的下一個(gè)位置
用數(shù)組實(shí)現(xiàn)的隊(duì)列叫作順序隊(duì)列
用鏈表實(shí)現(xiàn)的隊(duì)列叫作鏈?zhǔn)疥?duì)列
時(shí)間復(fù)雜度
入隊(duì)和出隊(duì)都是O(1)
應(yīng)用
資源池、消息隊(duì)列、命令隊(duì)列等等
概念
散列表也叫作哈希表(hash table),這種數(shù)據(jù)結(jié)構(gòu)提供了鍵(Key)和值(Value)的映射關(guān)系。只要
給出一個(gè)Key,就可以高效查找到它所匹配的Value,時(shí)間復(fù)雜度接近于O(1)。
存儲(chǔ)原理
哈希函數(shù)
散列表在本質(zhì)上也是一個(gè)數(shù)組
散列表的Key則是以字符串類型為主的
通過(guò)hash函數(shù)把Key和數(shù)組下標(biāo)進(jìn)行轉(zhuǎn)換
作用是把任意長(zhǎng)度的輸入通過(guò)散列算法轉(zhuǎn)換成固定類型、固定長(zhǎng)度的散列值
以Java為例:
//數(shù)組下標(biāo)=取key的hashcode模數(shù)組的長(zhǎng)度后的余數(shù)
index = HashCode (Key) % Array.length
int index=Math.abs("Hello".hashCode())%10; (0-9)
這是最簡(jiǎn)單的計(jì)算方式
還有很多hash函數(shù):CRC16、CRC32、siphash 、murmurHash、times 33等
此種Hash計(jì)算方式為固定Hash方式,也稱為傳統(tǒng)Hash
該方式在數(shù)組固定時(shí),可以快速檢索
但當(dāng)數(shù)組長(zhǎng)度變化時(shí),需要重新計(jì)算數(shù)組下標(biāo),此時(shí)根據(jù)key檢索將出現(xiàn)問(wèn)題
所以說(shuō)傳統(tǒng)Hash法雖然比較簡(jiǎn)單,但不利于擴(kuò)展,如果要擴(kuò)展可以采用一致性Hash法
時(shí)間復(fù)雜度
寫操作: O(1) + O(m) = O(m) m為單鏈元素個(gè)數(shù)
讀操作:O(1) + O(m) m為單鏈元素個(gè)數(shù)
Hash沖突寫單鏈表:O(m)
Hash擴(kuò)容:O(n) n是數(shù)組元素個(gè)數(shù) rehash
Hash沖突讀單鏈表:O(m) m為單鏈元素個(gè)數(shù)
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):讀寫快
缺點(diǎn):哈希表中的元素是沒(méi)有被排序的、Hash沖突、擴(kuò)容 重新計(jì)算
應(yīng)用
HashMap
位圖:位圖就是bitmap的縮寫。所謂bitmap,就是用每一位來(lái)存放某種狀態(tài),適用于大規(guī)模數(shù)據(jù),但數(shù)據(jù)狀態(tài)又不是很多的情況。通常是用來(lái)判斷某個(gè)數(shù)據(jù)存不存在的。在STL中有一個(gè)bitset容器,其實(shí)就是位圖。
概念
樹(shù)(tree)是n(n≥0)個(gè)節(jié)點(diǎn)的有限集。
當(dāng)n=0時(shí),稱為空樹(shù)。在任意一個(gè)非空樹(shù)中,有如下特點(diǎn)。
有且僅有一個(gè)特定的稱為根的節(jié)點(diǎn)。
當(dāng)n>1時(shí),其余節(jié)點(diǎn)可分為m(m>0)個(gè)互不相交的有限集
每一個(gè)集合本身又是一個(gè)樹(shù),并稱為根的子樹(shù)。
概念
二叉樹(shù)(binary tree)是樹(shù)的一種特殊形式。二叉,顧名思義,這種樹(shù)的每個(gè)節(jié)點(diǎn)最多有2個(gè)孩子節(jié)
點(diǎn)。注意,這里是最多有2個(gè),也可能只有1個(gè),或者沒(méi)有孩子節(jié)點(diǎn)。
滿二叉樹(shù)要求所有分支都是滿的;而完全二叉樹(shù)只需保證最后一個(gè)節(jié)點(diǎn)之前的節(jié)點(diǎn)都齊全即可
存儲(chǔ)
二叉樹(shù)屬于邏輯結(jié)構(gòu),可以使用鏈表和數(shù)組進(jìn)行存儲(chǔ)。
所以二叉樹(shù)一般用鏈表存儲(chǔ)實(shí)現(xiàn)。(二叉堆除外)
時(shí)間復(fù)雜度
二叉查找樹(shù)的插入和查找時(shí)間復(fù)雜度為:O(logn)
極端情況下二叉查找樹(shù)退化成鏈表,時(shí)間復(fù)雜度為O(n),所以需要平衡二叉查找樹(shù)。
應(yīng)用
非線性數(shù)據(jù):菜單,組織結(jié)構(gòu)、家譜等等
線性數(shù)據(jù):二叉查找樹(shù)
二叉查找樹(shù)是有序的,我們只需要中序遍歷,就可以在 O(n) 的時(shí)間復(fù)雜度內(nèi),輸出有序的數(shù)據(jù)序列。
二叉查找樹(shù)的性能非常穩(wěn)定,擴(kuò)容很方便(鏈表實(shí)現(xiàn))
概念
圖(Graph),是一種復(fù)雜的非線性表結(jié)構(gòu)。
圖中的元素我們就叫做頂點(diǎn)(vertex)
圖中的一個(gè)頂點(diǎn)可以與任意其他頂點(diǎn)建立連接關(guān)系。我們把這種建立的關(guān)系叫做邊(edge)
跟頂點(diǎn)相連接的邊的條數(shù)叫做度(degree)
圖這種結(jié)構(gòu)有很廣泛的應(yīng)用,比如社交網(wǎng)絡(luò),電子地圖,多對(duì)多的關(guān)系就可以用圖來(lái)表示。
邊有方向的圖叫做有向圖,比如A點(diǎn)到B點(diǎn)的直線距離,微信的添加好友是雙向的
邊無(wú)方向的圖叫無(wú)向圖,比如網(wǎng)絡(luò)拓?fù)鋱D
帶權(quán)圖(weighted graph)。在帶權(quán)圖中,每條邊都有一個(gè)權(quán)重(weight),我們可以通過(guò)這個(gè)權(quán)重
來(lái)表示 一些可度量的值
存儲(chǔ)原理
圖最直觀的一種存儲(chǔ)方法就是,鄰接矩陣(Adjacency Matrix)。
鄰接矩陣的底層是一個(gè)二維數(shù)組
無(wú)向圖:如果頂點(diǎn) i 與頂點(diǎn) j 之間有邊,我們就將 A[i][j]和 A[j][i]標(biāo)記為 1
有向圖
如果頂點(diǎn) i 到頂點(diǎn) j 之間,有一條箭頭從頂點(diǎn) i 指向頂點(diǎn) j 的邊,那我們就將 A[i][j]標(biāo)記為 1。同理,如
果有一條箭頭從頂點(diǎn) j 指向頂點(diǎn) i 的邊,我們就將 A[j][i]標(biāo)記為 1
帶權(quán)圖
數(shù)組中就存儲(chǔ)相應(yīng)的權(quán)重
時(shí)間復(fù)雜度
鄰接表
每個(gè)頂點(diǎn)都需要被訪問(wèn)一次,時(shí)間復(fù)雜度是 O(V);相連的頂點(diǎn)(也就是每條邊)也都要被訪問(wèn)一次,加
起來(lái)就是 O(E)。因此整體時(shí)間復(fù)雜度就是 O(V+E)。
鄰接矩陣
V 個(gè)頂點(diǎn),每次都要檢查每個(gè)頂點(diǎn)與其他頂點(diǎn)是否有聯(lián)系,因此時(shí)間復(fù)雜度是 O( V2)。
應(yīng)用
廣度優(yōu)先的搜索可以同時(shí)從起始點(diǎn)和終點(diǎn)開(kāi)始進(jìn)行,稱之為雙端 BFS。這種算法往往可以大大地提高搜
索的效率。
社交網(wǎng)絡(luò)可以用圖來(lái)表示。這個(gè)問(wèn)題就非常適合用圖的廣度優(yōu)先搜索算法來(lái)解決,因?yàn)閺V度優(yōu)先搜索是
層層往外推進(jìn)的。首先,遍歷與起始頂點(diǎn)最近的一層頂點(diǎn),也就是用戶的一度好友,然后再遍歷與用戶
距離的邊數(shù)為 2 的頂點(diǎn),也就是二度好友關(guān)系,以及與用戶距離的邊數(shù)為 3 的頂點(diǎn),也就是三度好友關(guān)
系。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
名稱欄目:【算術(shù)】數(shù)據(jù)結(jié)構(gòu)-創(chuàng)新互聯(lián)
當(dāng)前地址:http://bm7419.com/article24/dehhje.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、微信公眾號(hào)、建站公司、外貿(mào)建站、網(wǎng)站內(nèi)鏈、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容