n21v2存儲塊數據
㈠ 計算機網路(3)| 數據鏈路層
數據鏈路層屬於計算機網路的低層。數據鏈路層使用的信道主要是兩種類型:
(1)點對點信道 。即信道使用的是一對一點對點通信方式。
(2)廣播信道 。這種信道使用的是一對多的光播通信方式,相對復雜。在廣播信道上連接的主機很多,因此必須使用專用的共享信道協議來協調這些主機的數據發送。
首先我們應該了解一些有關點對點信道的一點基本概念。
(1)數據鏈路 。值得是當我們需要在一條線路上傳送數據時,除了有一條物理線路外(鏈路),還必須有一些必要的通信協議來控制這些數據的傳輸,若把實現這些協議的硬體和軟體加到鏈路上就構成了數據鏈路。
(2)幀 。幀指的是點對點信道的數據鏈路層的協議數據單元,即數據鏈路層把網路層交下來的數據構成幀發送到鏈路上以及把接收到的幀中的數據取出並上交給網路層。
點對點信道的數據鏈路層在進行通信時的主要步驟如下:
(1)結點A的數據鏈路層把網路層交下來的IP數據報添加首部和尾部封裝成幀。
(2)結點A把封裝好的幀發送給結點B的數據鏈路層。
(3)若B接收的幀無差錯,則從接收的幀中提取出IP數據報上交給上面的網路層;否則丟棄這個幀。
接下來是來介紹數據鏈路層的三個基本問題,而這三個問題對於各種數據鏈路層的協議都是通用的。
(1)封裝成幀 。指的是在一段數據的前後分別添加首部和尾部,這樣就構成了一個幀,從而能夠作為數據鏈路層的基本單位進行數據傳輸。在發送幀時,是從幀的首部開始發送的。各種數據鏈路層協議都對幀首部和幀尾部的格式有著明確的規定,且都規定了所能傳送的 幀的數據部分 長度上限—— 最大傳送單元MTU 。首部和尾部的作用是進行幀定界,幀定界可以使用特殊的 幀定界符 ,當數據在傳輸中出現差錯時,通過幀的幀定界符就可以知道收到的數據是一個不完整的幀(即只有首部開始符而沒有結束符)。
(2)透明傳輸 。從上面的介紹中知道幀的開始和結束標記使用了專門的控制字元,因此所傳輸的數據中任何與幀定界符相同的比特編碼是不允許出現的,否則就會出現幀定界錯誤。當傳送的幀是用文本文件組成的幀時,它的數據部分一定不會出現和幀定界符相同的字元,這樣的傳輸就叫做 透明傳輸 。為了解決其他類型文件傳輸時產生的透明傳輸問題,就將幀定界符的前面插入一個 轉義字元ESC ,這種方法稱為 位元組填充 。如果轉義字元也出現在數據中,就在轉義字元前面加上一個轉義字元,當接收端收到兩個轉義字元時,就刪除前面的那一個。
(3)差錯檢測 。在現實中,通信鏈路都不會是完美的,在傳輸比特的過程當中都是會產生差錯的,1變成0或者0變成1都是可能發生的,我們把這樣的錯誤叫做差錯檢測。在數據鏈路層中,為了保證數據傳輸的可靠性,減少差錯出現的數量,就會採用各種差錯檢測措施,目前最常使用的檢錯技術是 循環冗餘校驗 。它的原理簡單來說就是在被傳輸的數據M後面添加供錯檢測用的n為冗餘碼,構成一個幀數據發送出去。關於n位冗餘碼的得出方式與檢驗方式,可以 點擊這里進一步了解 。
對於點對點鏈路,點對點協議PPP是目前使用得最廣泛的數據鏈路層協議。由於網際網路的用戶通常都要連接到某個ISP才能接入到網際網路,PPP協議就是用戶計算機和ISP進行通信所使用的數據鏈路層協議。
在設計PPP協議時必須要考慮以下多方面的需求:
(1)簡單 。簡單的設計可使協議在實現時不容易出錯,這樣使得不同廠商對協議的不同實現的互操作性提高了。
(2)封裝成幀 。PPP協議必須規定特殊的字元作為幀定界符(即標志一個幀的開始和結束的字元),以便使接收端從收到的比特流中能准確的找出幀的開始和結束的位置。
(3)透明性 。PPP協議必須保證數據傳輸的透明性。如果說是數據中碰巧出現和幀定界符一樣的比特組合時,就要採用必要的措施來解決。
(4)多種網路層協議 。PPP協議必須能夠在同一條物理鏈路上同時支持多種網路層協議(IP和IPX等)的運行。
(5)多種類型鏈路 。除了要支持多種網路層的協議外,PPP還必須能夠在多種鏈路上運行(串列與並行鏈路)。
(6)差錯檢測 。PPP協議必須能夠對接收端收到的幀進行檢測,並舍棄有差錯的幀。
(7)檢測連接狀態 。必須具有一種機制能夠及時(不超過幾分鍾)自動檢測出鏈路是否處於正常工作狀態。
(8)最大傳送單元 。協議對每一種類型的點對點鏈路設置最大傳送單元MTU。
(9)網路層地址協商 。協議必須提供一種機制使通信的兩個網路層(如兩個IP層)的實體能夠通過協商知道或能夠配置彼此的網路層地址。
(10)數據壓縮協商 。協議必須能夠提供方法來協商使用數據壓縮演算法。但PPP協議不要求將數據壓縮演算法進行標准化。
PPP協議主要是由三個方面組成的:
(1) 一個將IP數據報封裝到串列鏈路的方法。
(2) 一個用來建立、配置和測試數據鏈路連接的鏈路控制協議LCP(Link Control Protocol)。
(3) 一套網路控制協議NCP(Network Control Protocol),其中的每一個協議支持不同的網路層協議,如IP、OSI的網路層、DECnet,以及AppleTalk等。
最後來介紹PPP協議幀的格式:
首先是各個欄位的意義。首部中的地址欄位A規定為0xFF,控制欄位C規定為0x03,這兩個欄位並沒有攜帶PPP幀的信息。首部的第一個欄位和尾部的第二個欄位都是標識欄位F(Flag)。首部的第四個欄位是2位元組的協議欄位。當協議欄位為0x0021時,PPP幀的信息部分欄位就是IP數據報。若為0xC021,則信息欄位是PPP鏈路控制協議LCP的數據,而 0x8021表示這是網路層的控制數據。尾部中的第一個欄位(2位元組)是使用CRC的幀檢驗序列FCS。
接著是關於PPP協議的差錯檢測的方法,主要分為位元組填充和零比特填充。當是PPP非同步傳輸時,採用的是位元組填充的方法。位元組填充是指當信息欄位中出現和標志欄位一樣的比特(0x7E)組合時,就必須採取一些措施使這種形式上和標志欄位一樣的比特組合不出現在信息欄位中。而當PPP協議使用的是同步傳輸時,就會採用零比特填充方法來實現透明傳輸,即只要發現有5個連續1,則立即填入一個0的方法。
廣播信道可以進行一對多的通信。由於區域網採用的就是廣播通信,因此下面有關廣播通信的討論就是基於區域網來進行的。
首先我們要知道區域網的主要 特點 ,即網路為一個單位所擁有,且地理范圍和站點數目均有限。在區域網才出現時,區域網比廣域網有著較高的數據率、較低的時延和較小的誤碼率。
區域網的 優點 主要有一下幾個方面:
(1) 具有廣播功能,從一個站點可方便地訪問全網。
(2) 便於系統的擴展和逐漸地演變,各設備的位置可靈活地調整和改變。
(3) 提高了系統的可靠性(reliability)、可用性(availibility)、生存性(survivability)。
關於區域網的分類,我們一般是對區域網按照網路拓撲進行分類:
1.星狀網: 由於集線器的出現和雙絞線大量用於區域網中,星形乙太網和多級星形結構的乙太網獲得了非常廣泛的應用。
2.環形網: 顧名思義,就是將各個主機像環一樣串起來的拓撲結構,最典型的就是令牌環形網。
3.匯流排網: 各站直接連在匯流排上。匯流排兩端的匹配電阻吸收在匯流排上傳播的電磁波信號的能量,避免在匯流排上產生有害的電磁波反射。
乙太網主要有兩個標准,即DIX Ethernet V2和IEEE 802.3標准,這兩種標準的差別很小,可以不是很嚴格的區分它們。
但是由於有關廠商的商業上的激烈競爭,導致IEEE 802委員會未能形成一個最佳的區域網標准而制定了幾個不同的區域網標准,所以為了數據鏈路層能夠更好的適應各種不同的標准,委員會就把區域網的數據鏈路層拆成兩個子層: 邏輯鏈路控制LLC子層 和 媒體接入控制MAC子層 。
計算機與外界區域網的連接是通過通信適配器(adapter)來進行的。適配器本來是在電腦主機箱內插入的一塊網路介面板(或者是在筆記本電腦中插入一塊PCMCIA卡),這種介面板又稱為網路介面卡NIC(Network Interface Card)或簡稱為網卡。適配器和區域網之間的通信是通過電纜或雙絞線以串列傳輸方式進行的,而適配器和計算機之間的通信則是通過計算機主板上的I/O匯流排以並行傳輸方式進行的,因此適配器的一個重要功能就是要進行數據串列傳輸和並行傳輸的轉換。由於網路上的數據率和計算機匯流排上的數據率並不相同,所以在適配器中必須裝有對數據進行緩存的存儲晶元。若在主板上插入適配器時,還必須把管理該適配器的設備驅動程序安裝在計算機的操作系統中。這個驅動程序以後就會告訴適配器,應當從存儲器的什麼位置上把多長的數據塊發送到區域網,或應當在存儲器的什麼位置上把區域網傳送過來的數據塊存儲下來。適配器還要能夠實現乙太網協議。
要注意的是,適配器在接收和發送各種幀時是不使用計算機的CPU的,所以這時計算機中的CPU可以處理其他的任務。當適配器收到有差錯的幀時,就把這個幀丟棄而不必通知計算機,而當適配器收到正確的幀時,它就使用中斷來通知該計算機並交付給協議棧中的網路層。當計算機要發送IP數據報時,就由協議棧把IP數據報向下交給適配器,組裝成幀後發送到區域網。特別注意: 計算機的硬體地址—MAC地址,就在適配器的ROM中。計算機的軟體地址—IP地址,就在計算機的存儲器中。
CSMA/CD協議主要有以下3個要點:
1.多點接入 :指的是這是匯流排型網路,許多計算機以多點接入的方式連接在一根匯流排上。
2.載波監聽 :就是用電子技術檢測匯流排上有沒有其他的計算機也在發送。載波監聽也稱為檢測信道,也就是說,為了獲得發送權,不管在發送前,還是在發送中,每一個站都必須不停的檢測信道。如果檢測出已經有其他站在發送,則自己就暫時不發送數據,等到信道空閑時才發送數據。而在發送中檢測信道是為了及時發現有沒有其他站的發送和本站發送的碰撞。
3.碰撞檢測 :也就是邊發送邊監聽。適配器一邊發送數據一邊檢測信道上的信號電壓的變化情況,以便判斷自己在發送數據時其他站是否也在發送數據。所謂碰撞就是信號之間產生了沖突,這時匯流排上傳輸的信號嚴重失真,無法從中恢復出有用的信息來。
集線器的一些特點如下:
(1)使用集線器的乙太網在邏輯上仍然是一個匯流排網,各個站點共享邏輯上的匯流排,使用的還是CSMA/CD協議。
(2)一個集線器是有多個介面。一個集線器就像一個多介面的轉發器。
(3)集線器工作在物理層,所以它的每一個介面僅僅是簡單的轉發比特。它不會進行碰撞檢測,所以當兩個介面同時有信號的輸入,那麼所有的介面都將收不到正確的幀。
(4)集線器自身採用了專門的晶元來進行自適應串音回波抵消。這樣可使介面轉發出去的較強的信號不致對該介面收到的較弱信號產生干擾。
(5)集線器一般都有少量的容錯能力和網路管理能力,也就是說如果在乙太網中有一個適配器出現了故障,不停地發送乙太網幀,這是集線器可以檢測到這個問題從而斷開與故障適配器的連線。
在區域網中,硬體地址又稱為物理地址或者MAC地址,這種地址是用在MAC幀中的。由於6位元組的地址欄位可以使全世界所有的區域網適配器具有不同的地址,所以現在的區域網適配器都是使用6位元組MAC地址。
主要負責分配地址欄位的6個位元組中的前3個位元組。世界上凡事要生產局域適配器的廠家都必須向IEEE購買這3個位元組構成的地址號,這個地址號我們通常叫做 公司標識符 ,而地址欄位的後3個位元組則由廠家自行指派,稱為 擴展標識符 。
IEEE規定地址欄位的第一位元組的最低位為I/G位。當I/G位為0時,地址欄位表示一個單個站地址,而當I/G位為1時表示組地址,用來進行多播。所以IEEE只分配地址欄位前三個位元組中的23位,當I/G位分別為0和1時,一個地址塊可分別生 2^24 個單個站地址和2^24個組地址。IEEE還把地址欄位第1個位元組的最低第二位規定為G/L位。當G/L位為0時是全球管理,來保證在全球沒有相同的地址,廠商向IEEE購買的都屬於全球管理。當地址段G/L位為1時是本地管理,這時用戶可以任意分配網路上的地址,但是乙太網幾乎不會理會這個G/L位的。
適配器對MAC幀是具有的過濾功能的,當適配器從網路上每收到一個MAC幀就先用硬體檢查MAC幀中的目的地址。如果是發往本站的幀則收下,然後再進行其他的處理,否則就將此幀丟棄。這樣做就可以不浪費主機的處理機和內存資源這里發往本站的幀包括以下三種幀:
(1)單播幀:即收到的幀的MAC地址與本站的硬體地址相同。
(2)廣播幀:即發送給本區域網上所有站點的幀。
(3)多播幀:即發送給本區域網上一部分站點的幀。
常用的乙太網MAC幀格式是乙太網V2的MAC幀格式。如下圖:
可以看到乙太網V2的MAC幀比較的簡單,有五個欄位組成。前兩個欄位分別為6位元組長的目的地址和源地址欄位。第三個欄位是2位元組的類型欄位,用來標志上一層使用的是什麼協議,以便把收到的MAC幀的數據上交給上一層的這個協議。下一個欄位是數據欄位,其長度在46到1500位元組之間。最後一個欄位是4位元組的幀檢驗序列FCS(使用CRC檢驗)。
從圖中可以看出,採用乙太網V2的MAC幀並沒有一個結構來存儲一個數據的幀長度。這是由於在曼徹斯特編碼中每一個碼元的正中間一定有一次電壓的轉換,如果當發送方在發送完一個MAC幀後就不再發送了,則發送方適配器的電壓一定是不會在變化的。這樣接收方就可以知道乙太網幀結束的位置,在這個位置減去FCS序列的4個位元組,就可以知道幀的長度了。
當數據欄位的長度小於42位元組時,MAC子層就會在MAC幀後面加入一個整數位元組來填充欄位,來保證乙太網的MAC幀的長度不小於64位元組。當MAC幀傳送給上層協議後,上層協議必須具有能夠識別填充欄位的功能。當上層使用的是IP協議時,其首部就有一個總長度欄位,因此總長度加上填充欄位的長度,就是MAC幀的數據欄位的長度。
從圖中還可以看出,在傳輸MAC幀時傳輸媒體上實際是多發送了8個位元組,這是因為當MAC幀開始接收時,由於適配器的時鍾尚未與比特流達成同步,因此MAC幀的最開始的部分是無法接收的,結果就是會使整個MAC成為無用幀。所以為了接收端能夠迅速的與比特流形成同步,就需要在前面插入這8個位元組。這8個位元組是由兩個部分組成的,第一個部分是由前7個位元組構成的前同步碼,它的主要作用就是就是實現同步。第二個部分是幀開始界定符,它的作用就是告訴接收方MAC幀馬上就要來了。需要注意的是,幀與幀之間的傳輸是需要一定的間隔的,否則接收端在收到了幀開始界定符後就會認為後面的都是MAC幀而會造成錯誤。
乙太網上的主機之間的距離不能太遠,否則主機發送的信號經過銅線的傳輸就會衰減到使CSMA/CD協議無法正常工作,所以在過去常常使用工作在物理層的轉發器來拓展乙太網的地理覆蓋范圍。但是現在隨著雙絞線乙太網成為乙太網的主流類型,拓展乙太網的覆蓋范圍已經很少使用轉發器,而是使用光纖和一對光纖數據機來拓展主機和集線器之間的距離。
光纖解調器的作用是進行電信號與光信號的轉換。由於光纖帶來的時延很小,並且帶寬很寬,所以才用這種方法可以很容易地使主機和幾公里外的集線器相連接。
如果是使用多個集線器,就可以連接成覆蓋更大范圍的多級星形結構的乙太網:
使用多級星形結構的乙太網不僅能夠讓連接在不同的乙太網的計算機能夠進行通信,還可以擴大乙太網的地理覆蓋范圍。但是這樣的多級結構也帶來了一些缺點,首先這樣的結構會增大它們的碰撞域,這樣做會導致圖中的某個系的兩個站在通信時所傳送的數據會通過所有的集線器進行轉發,使得其他系的內部在這時都不能進行通信。其次如果不同的乙太網採用的是不同的技術,那麼就不可能用集線器將它們互相連接起來。
拓展乙太網的更常用的方法是在數據鏈路層中進行的,在開始時人們使用的是網橋。但是現在人們更常用的是 乙太網交換機 。
乙太網交換機實質上是一個多介面的網橋,通常是有十幾個或者更多的介面,而每一個介面都是直接與一個單台主機或者另一個乙太網交換機相連。同時乙太網交換機還具有並行性,即能同時連通多對介面,使多對主機能同時通信,對於相互通信的主機來說都是獨占傳輸媒體且無碰撞的傳輸數據。
乙太網交換機的介面還有存儲器,能夠在輸出埠繁忙時把到來的幀進行緩存,等到介面不再繁忙時再將緩存的幀發送出去。
乙太網交換機還是一種即插即用的設備,它的內部的地址表是通過自學習演算法自動的建立起來的。乙太網交換機由於使用了專用的交換結構晶元,用硬體轉發,它的轉發速率是要比使用軟體轉發的網橋快很多。
如下圖中帶有4個介面的乙太網交換機,它的4個介面各連接一台計算機,其MAC地址分別為A、B、C、D。在開始時,乙太網交換機裡面的交換表是空的。
首先,A先向B發送一幀,從介面1進入到交換機。交換機收到幀後,先查找交換表,但是沒有查到應從哪個介面轉發這個幀,接著交換機把這個幀的源地址A和介面1寫入交換表中,並向除介面1以外的所有介面廣播這個幀。C和D因為目的地址不對會將這個幀丟棄,只有B才收下這個目的地址正確的幀。從新寫入的交換表(A,1)可以得出,以後不管從哪一個介面收到幀,只要其目的地址是A,就應當把收到的幀從介面1轉發出去。以此類推,只要主機A、B、C也向其他主機發送幀,乙太網交換機中的交換表就會把轉發到A或B或C應當經過的借口號寫入到交換表中,這樣交換表中的項目就齊全了,以後要轉發給任何一台主機的幀,就都能夠很快的在交換表中找到相應的轉發介面。
考慮到有時可能要在交換機的介面更換主機或者主機要更換其網路適配器,這就需要更改交換表中的項目,所以交換表中每個項目都設有一定的有效時間。
但是這樣的自學習有時也會在某個環路中無限制的兜圈子,如下圖:
假設一開始主機A通過介面交換機#1向主機B發送一幀。交換機#1收到這個幀後就向所有其他介面進行廣播發送。其中一個幀的走向:離開#1的3->交換機#2的介面1->介面2->交換機#1的介面4->介面3->交換機#2的介面1......一直循環下去,白白消耗網路資源。所以為了解決這樣的問題,IEEE制定了一個生成樹協議STP,其要點就是不改變網路的實際拓撲,但在邏輯上切斷某些鏈路,從而防止出現環路。
虛擬區域網VLAN是由一些區域網網段構成的與物理位置無關的邏輯組,而這些網段具有某些共同的需求。每一個VLAN的幀都有一個明確的標識符,指明發送這個幀的計算機屬於VLAN。要注意虛擬區域網其實只是區域網給用戶提供的一種服務,而不是一種新型區域網。
現在已經有標準定義了乙太網的幀格式的擴展,以便支持虛擬區域網。虛擬區域網協議允許在乙太網的幀格式中插入一個4位元組的標識符,稱為VLAN標記,它是用來指明發送該幀的計算機屬於哪一個虛擬區域網。VLAN標記欄位的長度是4位元組,插入在乙太網MAC幀的源地址欄位和類型欄位之間。VLAN標記的前兩個位元組總是設置為0x8100,稱為IEEE802.1Q標記類型。當數據鏈路層檢測到MAC幀的源地址欄位後面的兩個位元組的值是0x8100時,就知道現在插入了4位元組的VLAN標記。於是就接著檢查後面兩個位元組的內容,在後面的兩個位元組中,前3位是用戶優先順序欄位,接著的一位是規范格式指示符CFI,最後的12位是該虛擬區域網VLAN標識符VID,它唯一的標志了這個以台網屬於哪一個VLAN。
高速乙太網主要是分為三種,即100BASE-T乙太網、吉比特乙太網和10吉比特乙太網:
㈡ 鄰接表的網路存儲空間很大嗎
在具體講解鄰接表存儲圖的實現方法之前,先普及一個"鄰接點"的概念。在圖中,如果兩個點相互連通,即通過其中一個頂點,可直接找到另一個頂點,則稱它們互為鄰接點。
鄰接指的是圖中頂點之間有邊或者弧的存在。
鄰接表存儲圖的實現方式是,給圖中的各個頂點獨自建立一個鏈表,用節點存儲該頂點,用鏈表中其他節點存儲各自的臨界點。
與此同時,為了便於管理這些鏈表,通常會將所有鏈表的頭節點存儲到數組中(也可以用鏈表存儲)。也正因為各個鏈表的頭節點存儲的是各個頂點,因此各鏈表在存儲臨界點數據時,僅需存儲該鄰接頂點位於數組中的位置下標即可。
例如,存儲圖 1a) 所示的有向圖,其對應的鄰接表如圖 1b) 所示:
鄰接表存儲有向圖
圖 1 鄰接表存儲有向圖
拿頂點 V1 來說,與其相關的鄰接點分別為 V2 和 V3,因此存儲 V1 的鏈表中存儲的是 V2 和 V3 在數組中的位置下標 1 和 2。
從圖 1 中可以看出,存儲各頂點的節點結構分為兩部分,數據域和指針域。數據域用於存儲頂點數據信息,指針域用於鏈接下一個節點,如圖 2 所示:
鄰接表節點結構
圖 2 鄰接表節點結構
在實際應用中,除了圖 2 這種節點結構外,對於用鏈接表存儲網(邊或弧存在權)結構,還需要節點存儲權的值,因此需使用圖 3 中的節點結構:
鄰接表存儲網結構使用的節點
圖 3 鄰接表存儲網結構使用的節點
圖 1 中的鏈接表結構轉化為對應 C 語言代碼如下:
#define MAX_VERTEX_NUM 20//最大頂點個數
#define VertexType int//頂點數據的類型
#define InfoType int//圖中弧或者邊包含的信息的類型
typedef struct ArcNode{
int adjvex;//鄰接點在數組中的位置下標
struct ArcNode * nextarc;//指向下一個鄰接點的指針
InfoType * info;//信息域
}ArcNode;
typedef struct VNode{
VertexType data;//頂點的數據域
ArcNode * firstarc;//指向鄰接點的指針
}VNode,AdjList[MAX_VERTEX_NUM];//存儲各鏈表頭結點的數組
typedef struct {
AdjList vertices;//圖中頂點的數組
int vexnum,arcnum;//記錄圖中頂點數和邊或弧數
int kind;//記錄圖的種類
}ALGraph;
鄰接表計算頂點的出度和入度
使用鄰接表計算無向圖中頂點的入度和出度會非常簡單,只需從數組中找到該頂點然後統計此鏈表中節點的數量即可。
而使用鄰接表存儲有向圖時,通常各個頂點的鏈表中存儲的都是以該頂點為弧尾的鄰接點,因此通過統計各頂點鏈表中的節點數量,只能計算出該頂點的出度,而無法計算該頂點的入度。
對於利用鄰接表求某頂點的入度,有兩種方式:
遍歷整個鄰接表中的節點,統計數據域與該頂點所在數組位置下標相同的節點數量,即為該頂點的入度;
建立一個逆鄰接表,該表中的各頂點鏈表專門用於存儲以此頂點為弧頭的所有頂點在數組中的位置下標。比如說,建立一張圖 1a) 對應的逆鄰接表:
逆鄰接表示意圖
對於具有 n 個頂點和 e 條邊的無向圖,鄰接表中需要存儲 n 個頭結點和 2e 個表結點。在圖中邊或者弧稀疏的時候,使用鄰接表要比前一節介紹的鄰接矩陣更加節省空間。
回答於 2022-11-01
搶首贊
老人用哪種造口袋方便-淘寶熱賣好物匯集,品牌眾多,放心購!
【買3送5】造口袋封條造口護理用品防漏夾子造瘺袋便袋封口條10根
¥42.75 元
怡康一件式開口造口袋造瘺袋人工肛門袋大便袋10個送尾夾2
¥50 元
造口褲掛尿袋褲子老年人褲膀胱造瘺膽手術後護理專用褲春夏薄款
¥116 元
造瘺褲病人護理褲腎造口腸道造口老人護理用品病人手術後裝尿袋褲
¥150 元
造瘺褲尿袋褲造口褲膀胱手術裝尿袋引流袋褲子病人護理褲老人專用
¥96 元
淘寶熱賣廣告
哪個牌子好護膚品-上淘寶選好物,輕松下單,放心購物!
哪個牌子好護膚品-淘寶熱賣好物,大牌匯聚,暢享購物!熱賣優質商品,淘你滿意!
淘寶熱賣廣告
護膚品有哪些品牌-淘寶熱賣好物匯集,品牌眾多,放心購!
護膚品有哪些品牌-購物上淘寶,品類集結,熱賣好物!海量優質商品,輕松暢購!盡享優惠,買東西上淘寶,一站輕松購!
廣告
數據結構,求無向圖用鄰接矩陣和鄰接表的存儲空間大小,怎麼算?
鄰接表所需的存儲空間為e(邊數),但不適合查詢兩點間是否存在路徑鄰接矩陣所需的存儲空間為你n^2,適合查詢兩點間是否存在路徑對於第二問,鄰接表所需的存儲空間為9900,鄰接矩陣所需的存儲空間為你n^2=10000,差不多,所以選性能更優的鄰接矩陣實際上像(2)這種稠密圖(其實是個滿圖)一般適合鄰接矩陣
司馬刀劍
1點贊1評論
更多專家
鄰接表的網路存儲空間很大嗎
專家1對1在線解答問題
5分鍾內響應 | 萬名專業答主
馬上提問
最美的花火 咨詢一個電子數碼問題,並發表了好評
lanqiuwangzi 咨詢一個電子數碼問題,並發表了好評
garlic 咨詢一個電子數碼問題,並發表了好評
188****8493 咨詢一個電子數碼問題,並發表了好評
籃球大圖 咨詢一個電子數碼問題,並發表了好評
動物樂園 咨詢一個電子數碼問題,並發表了好評
AKA 咨詢一個電子數碼問題,並發表了好評
圖解:什麼是「圖」?
作為圖的開始,我們先來看一個經典的問題,它被認為是圖論的起源。 歐拉在1735年提出,並沒有方法能圓滿解決這個問題,他更在第二年發表在論文《柯尼斯堡的七橋》中,證明符合條件的走法並不存在 歐拉把實際的抽象問題簡化為平面上的點與線組合,每一座橋視為一條線,橋所連接的地區視為點。這樣若從某點出發後最後再回到這點,則這一點的線數必須是偶數,這樣的點稱為偶頂點。相對的,連有奇數條線的點稱為奇頂點。由於柯尼斯堡七橋問題中存在4個奇頂點,它無法實現符合題意的遍歷。 之後,不少數學家都嘗試去解析這類事例。而這些解析,最後發展成為了數學中的圖論233。 圖是一種非線性表數據結構,圖中的元素我們叫做頂點,圖中建立的連接關系我們叫做邊。,圖主要分為四種:無向圖、有向圖、加權圖、加權有向圖。 我們把有邊有方向的圖叫做「有向圖」,把邊沒有方向的圖叫做「無向圖」,把邊帶有權重的圖叫做「加權圖」,這些概念其實都比較容易理解,你可以參考下面的幾幅圖對比一下。我們可以分別類比生活中的:知乎關注(有向)、微信交友(無向)和QQ好友親密度(帶權值)。 在圖的表示中,我們定義 度 的概念。對於無向圖而言,一個頂點的 度 是指跟該頂點相連接的邊的條數;對於有向圖而言,我們分別定義 入度 和 出度 ,頂點的入度表示有多少條邊指向這個節點,頂點的出度表示有多少條邊以這個節點為起點指向其他節點。 圖的存儲方法主要有兩種:鄰接表(Adjacency List)和鄰接矩陣(Adjacency Matrix)。我們首先來介紹一下這兩種存儲方法。 鄰接矩陣,顧名思義,就是利用矩陣去描述圖,它的底層依賴於一個二維數組。對於無向圖而言,如果 頂點i 與 頂點j 之間有邊,那麼我們就把 A[i][j] 和 A[j][i] 標記為1,它們之間沒有邊就標記為0;對於有向圖而言,如果 頂點 i 到 頂點 j 之間,有一條箭頭從 頂點 i 指向 頂點 j 的邊,那我們就將 A[i][j] 標記為 1。同理,如果有一條箭頭從 頂點j 指向 頂點 i 的邊,我們就將 A[j][i] 標記為 1。對於帶權圖,數組中就存儲相應的權重。 我們使用鄰接矩陣來表示圖,雖然的確很直觀明了,但是卻比較浪費空間。 其一,對於無向圖來說, A[i][j] 永遠等於 A[j][i] ,我們只需要使用一半矩陣就可以成功地表示,那另一半空間就被浪費掉了; 其二、如果我們存儲的是稀疏圖,也就是頂點很多,但每個頂點的邊並不很多,此時鄰接矩陣的存儲方法就更加浪費空間了。好比微信有好幾億的用戶,對應到圖上就是好幾億的頂點。但是每個用戶的好友並不會很多,一般也就幾百個而已。如果我們用鄰接矩陣來存儲,那絕大部分的存儲空間都被浪費了。 總結一下,當圖為稀疏圖、頂點較多,即圖結構比較大時,更適宜選擇鄰接表作為存儲結構。當圖為稠密圖、頂點較少時,使用鄰接矩陣作為存儲結構較為合適。 我們使用一個以頂點為索引的列表數組,其中數組中的每個元素都指向一個單獨的鏈表,該鏈表存儲了與數組中頂點相鄰的所有頂點。有點繞口,不過我為你准備了一張圖,我相信結合圖片你肯定可以更好地理解。 相比於鄰接矩陣, 鄰接表比較節省存儲空間,但是使用起來卻比較耗費時間 。不過, 它的形式更為自由和靈活 ,比如,在鏈表過長的情況下,我們可以把鏈表用平衡二叉查找樹(紅黑樹)替代,這樣的話就比較高效了。 好了,關於圖的內容就到這里了,我希望通過這篇文章你對於圖有了一個初步的認識!下一次,我們會介紹深度優先搜索和廣度優先搜索,小超與你不見不散!
㈢ 如何運用西門子PLC的變數存儲器及什麼程序能用到
用西門子PLC的變數存儲器V只有S7- 200中才有。相當於300中的M變數。按v1,v2,v3 位元組搞下去。
變數存儲器(V)(相當於內輔繼電器)PLC執行程序過程中,會存在一些控制過程的中間結果,這些中間數據也需要用存儲器來保存。變數存儲器就是根據這個實際的要求設計的。變數存儲器是S7-200CPU為保存中間變數數據而建立的一個存儲區,用V表示。可以按位、位元組、字、雙字四種方式來存取。(1)按「位」方式:從V0.0~I5119.7,共有40960點。CPU221、CPU222變數存儲器只有2048個位元組,其變數存儲區只能到V2047.7位。(2)按「位元組」方式:從VB0~VB5119,共有5120個位元組(3)按「字」方式:從VW0~VW5118,共有2560個字(4)按「雙字」方式:從VD0~VD5116,共有1280個雙字
(1) S7-200存儲器類型
S7-200 PLC可以採用多種形式的存儲器來進行PLC程序與數據的存儲,以防止數據的丟失。S7-200可以使用的存儲器主要有如下類型:
①RAM: CPU模塊本身帶有動態數據存儲器(RAM)。RAM用於存儲PLC的運算、處理結果等數據。根據需要,RAM的數據可以通過電容器或電池盒(選件)進行保持,但其存儲時間較短,一般只能保持幾天。
②EEPROM(或Flash ROM):除RAM外,CPU模塊本身帶有的保持型存儲器(EEPROM或Flash ROM),可以進行數據的永久性存儲。保持型存儲器用於存儲PLC用戶程序、PLC參數等重要數據;根據需要,也可以將PLC程序執行過程中所產生的局部變數V、內部標志M、定時器T、計數器C等保存在保持型存儲器中。
③存儲器卡:存儲器卡在S7-200中為可選件,用戶可以根據需要選用。存儲器卡為保持型存儲器,可以作為PLC保持型存儲器的擴展與後備,用於保存PLC用戶程序、PLC參數、變數V、內部標志M、定時器T、計數器C等。 (2)存儲器分區
S7-200的內部存儲器分為程序存儲區、數據存儲區、參數存儲區。其中,程序存儲區用於存儲PLC用戶程序;數據存儲區用於存儲PLC運算、 處理的中間結果(如輸入/輸出映像,標志、變數的狀態,計數器、定時器的中間值等);參數存儲區用於存儲PLC配置參數(包括程序保護密碼、地址分配設 定、停電保持區域的設定等)。
㈣ 哈密頓迴路的演算法
哈密頓路徑問題在上世紀七十年代初,終於被證明是「NP完備」的。據說具有這樣性質的問題,難於找到一個有效的演算法。實際上對於某些頂點數不到100的網路,利用現有最好的演算法和計算機也需要比較荒唐的時間(比如幾百年)才能確定其是否存在一條這樣的路徑。
從圖中的任意一點出發,路途中經過圖中每一個結點當且僅當一次,則成為哈密頓迴路。
要滿足兩個條件:
⒈封閉的環
⒉是一個連通圖,且圖中任意兩點可達
經過圖(有向圖或無向圖)中所有頂點一次且僅一次的通路稱為哈密頓通路。
經過圖中所有頂點一次且僅一次的迴路稱為哈密頓迴路。
具有哈密頓迴路的圖稱為哈密頓圖,具有哈密頓通路但不具有哈密頓迴路的圖稱為半哈密頓圖。
平凡圖是哈密頓圖。
⒊若以1到2、2到3、3到4、4到5、5到1,為計數規律,則各點均出現兩次;這種判斷方法在計算機編程運算中顯得尤為重要,其會精簡很多運算過程。
⒋新出爐,有待檢測的代碼如下:
%-------輸入的數據的原數據參照
% v1 v2 v3 v4 v5
%v1 0 20 1 11 2
%v2 0 0 9 1 3
%v3 0 0 0 13 8
%v4 0 0 0 0 6
%v5 0 0 0 0 0
%以上為輸入數據的原數據參照
%建議所計算的數據矩陣長度為5,不會產生bug,且不會對任何計算機造成計算負擔
%輸入數據矩陣長度可以超過5,但是最初計算出的n個最小值中,重復次數超過2的點的種類只允許為一種
a=[0 20 1 11 2
0 0 9 1 3
0 0 0 13 8
0 0 0 0 6
0 0 0 0 0];
l=length(a)
s1=inf
zp=inf
n2=1
f=a
f(a==0)=inf
b=zeros(l)
i1=0
while i1<=l-1
[r c]=find(f==min(min(f)))
b(r⑴,c⑴)=f(r⑴,c⑴)
f(r⑴,c⑴)=inf
i1=i1+1
end
f1=f
[rz cz]=find(b>0)
pathz=[rz cz]
pz=[rz;cz]
p2z=zeros(2*l,1)
i2z=1
n2z=0
while i2z<=2*l
[r2z c2z]=find(pz==pz(i2z,1))
k1z=size(r2z)
if k1z(1,1)>2
p2z(r2z,1)=pz(r2z,1)
n2z=n2z+1
end
i2z=i2z+1
end
if n2z==2
HHL=b
zp=sum(sum(b))
else
while min(min(f1))~=inf
if n2>2
b=snh
end
[r1 c1]=find(b>0)
path1=[r1 c1]
p1=[r1;c1]
p2=zeros(2*l,1)
i2=1
n2=0
while i2<=2*l
[r2 c2]=find(p1==p1(i2,1))
k1=size(r2)
if k1(1,1)>2
p2(r2,1)=p1(r2,1)
n2=n2+1
end
i2=i2+1
end
[r3 c3]=find(p2>0)
p3=zeros(l,2)
i3=0
while i3<=n2-1
if r3⑴<=l
p3(r3⑴,:)=path1(r3⑴,:)
else
p3(r3⑴-l,:)=path1(r3⑴-l,:)
end
r3⑴=[]
i3=i3+1
end
p3(p3==0)=[]
p3=reshape(p3,n2,2)
p8=p2
[r8 c8]=find(p8>0)
p9=p8
r9=r8
i4=1
while i4<=n2
f1(p9(r9⑴,1),:)=inf
f1(:,p9(r9⑴,1))=inf
r9⑴=[]
i4=i4+1
end
[r4 c4]=find(f1==min(min(f1)))
f1(r4,c4)=inf
b1=b
b1(r4,c4)=a(r4,c4)
i5=1
p4=p3
while i5<=n2
b1=b
b1(r4⑴,c4⑴)=a(r4⑴,c4⑴)
b1(p4(1,1),p4(1,2))=0
p4(1,:)=[]
[r5 c5]=find(b1>0)
p5=[r5;c5]
i6=1
n6=0
while i6<=2*l
[r6 c6]=find(p5==p5(i6,1))
k6=size(r6)
if k6(1,1)>2
n6=n6+1
end
i6=i6+1
end
if n6>2
if sum(sum(b1))<s1
snh=[]
s1=sum(sum(b1))
snh=b1
end
else
if sum(sum(b1))<zp
HHL=[]
zp=sum(sum(b1))
HHL=b1
end
end
i5=i5+1
end
end
[rs cs]=find(HHL>0)
minpaths=[rs cs]
journeys=zp
註:這段代碼採用分支定界法作為編寫程序的依據,因此代碼依舊局限在演算法上;而且代碼的使用對所要計算的數據是有要求的,如下:
⒈只要數據在開始計算出的n個最小值中,其重復次數超過2次的點的種類只能為一種,例如:代碼段中的數據五個最小值中其重復次數超過2次的點只有v5。
⒉數據矩陣格式要求:只允許為上三角矩陣,不支持全矩陣以及下三角矩陣的運算。
⒊代碼擴展方法請使用者獨立思考,不唯一。
⒋運算數據擴展方法,請使用者獨立思考,不唯一。
⒌此代碼為本人畢設的附加產品,不會對使用此代碼者,因理解不當或使用不當而造成的任何不良後果,付出任何責任。
⒍代碼僅供交流。
㈤ 在AT89C51系列單片機內有幾類存儲器存儲容量分別是多少
MCS-51單片機在物理結構上有四個存儲空間: 1、片內程序存儲器 2、片外程序存儲器 3、片內數據存儲器 4、片外數據存儲器 但在邏輯上,即從用戶的角度上,8051單片機有三個存儲空間: 1、片內外統一編址的64K的程序存儲器地址空間(MOVC) 2、256B的片內數據存儲器的地址空間(MOV) 3、以及64K片外數據存儲器的地址空間(MOVX) 在訪問三個不同的邏輯空間時,應採用不同形式的指令以產生不同的存儲器空間的選通信號。程序ROM 定址范圍:0000H ~ FFFFH 容量64KB EA = 1,定址內部ROM;EA = 0,定址外部ROM 地址長度:16位 作用: 存放程序及程序運行時所需的常數 數據存儲器片內數據存儲器為8位地址,所以最大可定址的范圍為256個單元地址,對片外數據存儲器採用間接定址方式,R0、R1和DPTR都可以做為間接定址寄存器,R0、R1是8位的寄存器,即R0、R1的定址范圍最大為256個單元,而DPTR是16位地址指針,定址范圍就可達到64KB。也就是說在定址片外數據存儲器時,定址范圍超過了256B,就不能用R0、R1做為間接定址寄存器,而必須用DPTR寄存器做為間接定址寄存器。其中片內數據存儲器分為兩部分,地址從00H—7FH單元(共128個位元組)為用戶數據RAM,從80H—FFH地址單元(也是128個位元組)為特殊寄存器(SFR)單元。
㈥ 東芝彩電21v2nc匯流排調整
1。更換存儲器後,開機按遙控器上的靜音鍵一次,同時按遙控上的靜音和電視上的菜單,進入S。
2。此時同時按遙控上的屏顯鍵和電視上的「節目+」完成初始化。
3。用頻道鍵選項目,用音量鍵調數據。
㈦ 資料庫解決了數據從邏輯結構到物理結構的存儲問題對嗎
數據結構有哪些》一節講到,數據的存儲方式可分為線性表、樹和圖三種存儲結構,而每種存儲結構又可細分為順序存儲結構和鏈式存儲結構。數據存儲方式如此之多,針對不同類型的數據選擇合適的存儲方式是至關重要的。
那麼,到底如何選擇呢?數據存儲結構的選擇取決於兩方面,即數據的邏輯結構和存儲結構(又稱物理結構)。
邏輯結構
數據的邏輯結構,簡單地理解,就是指的數據之間的邏輯關系。
家庭成員關系圖
圖 1 家庭成員關系圖
例如,圖 1 顯示是一張家庭的成員關系圖,從圖中可以看到,張平、張華和張群是兄弟,他們的父親是張亮,其中張平有兩個兒子,分別是張晶和張磊。
以上所說,父子、兄弟等這些關系都指的是數據間的邏輯關系,假設我們要存儲這樣一張家庭成員關系圖,不僅要存儲張平、張華等數據,還要存儲它們之間的關系,兩者缺一不可。
一組數據成功存儲到計算機的衡量標準是要能將其完整的復原。例如圖 1 所示的成員關系圖,如果所存儲的數據能將此成員關系圖徹底復原,則說明數據存儲成功。
「多對多」關系示意圖
圖 2 「多對多」關系示意圖
數據之間的邏輯關系可細分為三類,「一對一」、「一對多」和「多對多」:
「一對一」:類似集合 {1,2,3,...,n} 這類的數據,每個數據的左側有且僅有一個數據與其相鄰(除 1 外);同樣,每個數據的右側也只有一個數據與其相鄰(除 n 外),所有的數據都是如此,就說數據之間是「一對一」的邏輯關系;
「一對多」:圖 1 中的數據就屬於「一對多」,因為對於張平來說,有且僅有一個父親(張亮),但是有 2(多)個孩子;
「多對多」:拿圖 2 來說,從 V1 可以到達 V2、V3、V4,同樣,從 V2、V3、V4 也可以到達 V1,對於V1、V2、V3和V4來說,它們之間就是「多對多」的關系;
通過學習數據結構,我們可以學到 3 種存儲結構分別存儲這 3 類邏輯關系的數據,換句話說:
線性表用於存儲具有「一對一」邏輯關系的數據;
樹結構用於存儲具有「一對多」關系的數據;
圖結構用於存儲具有「多對多」關系的數據;
由此,我們可以通過分析數據之間的邏輯關系來決定使用哪種存儲結構,但具體使用順序存儲還是鏈式存儲,還要通過數據的物理結構來決定。
存儲結構(物理結構)
數據的存儲結構,也就是物理結構,指的是數據在物理存儲空間上選擇集中存放還是分散存放。假設要存儲大小為 10G 的數據,則集中存放就如圖 3a) 所示,分散存放就如圖 3b)所示。
數據的物理存儲方式
圖 3 數據的物理存儲方式
如果選擇集中存儲,就使用順序存儲結構;反之,就使用鏈式存儲。至於如何選擇,主要取決於存儲設備的狀態以及數據的用途。
我們知道,集中存儲(底層實現使用的是數組)需要使用一大塊連續的物理空間,假設要存儲大小為 1G 的數據,若存儲設備上沒有整塊大小超過 1G 的空間,就無法使用順序存儲,此時就要選擇鏈式存儲,因為鏈式存儲是隨機存儲數據,佔用的都是存儲設備中比較小的存儲空間,因此有一定幾率可以存儲成功。
並且,數據的用途不同,選擇的存儲結構也不同。將數據進行集中存儲有利於後期對數據進行遍歷操作,而分散存儲更有利於後期增加或刪除數據。因此,如果後期需要對數據進行大量的檢索(遍歷),就選擇集中存儲;反之,若後期需要對數據做進一步更新(增加或刪除),則選擇分散存儲。
㈧ 西門子200中數據塊是怎麼用的呀。請教,它的功能是什麼呀
具體使用方法如下:
1、一般背景數據塊才自動生成變數,是否可以改動或刪除要看程序怎樣寫,如果程序沒使用就可以刪除,可以在原來基礎上添加定義變數。
㈨ 數據結構——圖
轉自: http://www.cnblogs.com/mcgrady/archive/2013/09/23/3335847.html
閱讀目錄
一,圖的定義
二,圖相關的概念和術語
三,圖的創建和遍歷
四,最小生成樹和最短路徑
五,演算法實現
這一篇我們要總結的是圖(Graph),圖可能比我們之前學習的線性結構和樹形結構都要復雜,不過沒有關系,我們一點一點地來總結,那麼關於圖我想從以下幾點進行總結:
1,圖的定義?
2,圖相關的概念和術語?
3,圖的創建和遍歷?
4,最小生成樹和最短路徑?
5,演算法實現?
一,圖的定義
什麼是圖呢?
圖是一種復雜的非線性結構。
在線性結構中,數據元素之間滿足唯一的線性關系,每個數據元素(除第一個和最後一個外)只有一個直接前趨和一個直接後繼;
在樹形結構中,數據元素之間有著明顯的層次關系,並且每個數據元素只與上一層中的一個元素(雙親節點)及下一層的多個元素(孩子節點)相關;
而在圖形結構中,節點之間的關系是任意的,圖中任意兩個數據元素之間都有可能相關。
圖G由兩個集合V(頂點Vertex)和E(邊Edge)組成,定義為G=(V,E)
二,圖相關的概念和術語
1,無向圖和有向圖
對於一個圖,若每條邊都是沒有方向的,則稱該圖為無向圖。圖示如下:
因此,(Vi,Vj)和(Vj,Vi)表示的是同一條邊。注意,無向圖是用小括弧,而下面介紹的有向圖是用尖括弧。
無向圖的頂點集和邊集分別表示為:
V(G)={V1,V2,V3,V4,V5}
E(G)={(V1,V2),(V1,V4),(V2,V3),(V2,V5),(V3,V4),(V3,V5),(V4,V5)}
對於一個圖G,若每條邊都是有方向的,則稱該圖為有向圖。圖示如下。
因此,和是兩條不同的有向邊。注意,有向邊又稱為弧。
有向圖的頂點集和邊集分別表示為:
V(G)={V1,V2,V3}
E(G)={,,,}
2,無向完全圖和有向完全圖
我們將具有n(n-1)/2條邊的無向圖稱為無向完全圖。同理,將具有n(n-1)條邊的有向圖稱為有向完全圖。
3,頂點的度
對於無向圖,頂點的度表示以該頂點作為一個端點的邊的數目。比如,圖(a)無向圖中頂點V3的度D(V3)=3
對於有向圖,頂點的度分為入度和出度。入度表示以該頂點為終點的入邊數目,出度是以該頂點為起點的出邊數目,該頂點的度等於其入度和出度之和。比如,頂點V1的入度ID(V1)=1,出度OD(V1)=2,所以D(V1)=ID(V1)+OD(V1)=1+2=3
記住,不管是無向圖還是有向圖,頂點數n,邊數e和頂點的度數有如下關系:
因此,就拿有向圖(b)來舉例,由公式可以得到圖G的邊數e=(D(V1)+D(V2)+D(V3))/2=(3+2+3)/2=4
4,子圖
故名思義,這個就不解釋了。
5,路徑,路徑長度和迴路
路徑,比如在無向圖G中,存在一個頂點序列Vp,Vi1,Vi2,Vi3…,Vim,Vq,使得(Vp,Vi1),(Vi1,Vi2),…,(Vim,Vq)均屬於邊集E(G),則稱頂點Vp到Vq存在一條路徑。
路徑長度,是指一條路徑上經過的邊的數量。
迴路,指一條路徑的起點和終點為同一個頂點。
6,連通圖(無向圖)
連通圖是指圖G中任意兩個頂點Vi和Vj都連通,則稱為連通圖。比如圖(b)就是連通圖。下面是一個非連通圖的例子。
上圖中,因為V5和V6是單獨的,所以是非連通圖。
7,強連通圖(有向圖)
強連通圖是對於有向圖而言的,與無向圖的連通圖類似。
8,網
帶」權值」的連通圖稱為網。如圖所示。
三,圖的創建和遍歷
1,圖的兩種存儲結構
1) 鄰接矩陣,原理就是用兩個數組,一個數組保存頂點集,一個數組保存邊集。下面的演算法實現里邊我們也是採用這種存儲結構。如下圖所示:
2) 鄰接表,鄰接表是圖的一種鏈式存儲結構。這種存儲結構類似於樹的孩子鏈表。對於圖G中每個頂點Vi,把所有鄰接於Vi的頂點Vj鏈成一個單鏈表,這個單鏈表稱為頂點Vi的鄰接表。
2,圖的兩種遍歷方法
1) 深度優先搜索遍歷
深度優先搜索DFS遍歷類似於樹的前序遍歷。其基本思路是:
a) 假設初始狀態是圖中所有頂點都未曾訪問過,則可從圖G中任意一頂點v為初始出發點,首先訪問出發點v,並將其標記為已訪問過。
b) 然後依次從v出發搜索v的每個鄰接點w,若w未曾訪問過,則以w作為新的出發點出發,繼續進行深度優先遍歷,直到圖中所有和v有路徑相通的頂點都被訪問到。
c) 若此時圖中仍有頂點未被訪問,則另選一個未曾訪問的頂點作為起點,重復上述步驟,直到圖中所有頂點都被訪問到為止。
圖示如下:
註:紅色數字代表遍歷的先後順序,所以圖(e)無向圖的深度優先遍歷的頂點訪問序列為:V0,V1,V2,V5,V4,V6,V3,V7,V8
如果採用鄰接矩陣存儲,則時間復雜度為O(n2);當採用鄰接表時時間復雜度為O(n+e)。
2) 廣度優先搜索遍歷
廣度優先搜索遍歷BFS類似於樹的按層次遍歷。其基本思路是:
a) 首先訪問出發點Vi
b) 接著依次訪問Vi的所有未被訪問過的鄰接點Vi1,Vi2,Vi3,…,Vit並均標記為已訪問過。
c) 然後再按照Vi1,Vi2,… ,Vit的次序,訪問每一個頂點的所有未曾訪問過的頂點並均標記為已訪問過,依此類推,直到圖中所有和初始出發點Vi有路徑相通的頂點都被訪問過為止。
圖示如下:
因此,圖(f)採用廣義優先搜索遍歷以V0為出發點的頂點序列為:V0,V1,V3,V4,V2,V6,V8,V5,V7
如果採用鄰接矩陣存儲,則時間復雜度為O(n2),若採用鄰接表,則時間復雜度為O(n+e)。
四,最小生成樹和最短路徑
1,最小生成樹
什麼是最小生成樹呢?在弄清什麼是最小生成樹之前,我們需要弄清什麼是生成樹?
用一句語簡單概括生成樹就是:生成樹是將圖中所有頂點以最少的邊連通的子圖。
比如圖(g)可以同時得到兩個生成樹圖(h)和圖(i)
知道了什麼是生成樹之後,我們就很容易理解什麼是最小生成樹了。所謂最小生成樹,用一句話總結就是:權值和最小的生成樹就是最小生成樹。
比如上圖中的兩個生成樹,生成樹1和生成樹2,生成樹1的權值和為:12,生成樹2的權值為:14,我們可以證明圖(h)生成樹1就是圖(g)的最小生成樹。
那麼如何構造最小生成樹呢?可以使用普里姆演算法。
2,最短路徑
求最短路徑也就是求最短路徑長度。下面是一個帶權值的有向圖,表格中分別列出了頂點V1其它各頂點的最短路徑長度。
表:頂點V1到其它各頂點的最短路徑表
從圖中可以看出,頂點V1到V4的路徑有3條(V1,V2,V4),(V1,V4),(V1,V3,V2,V4),其路徑長度分別為15,20和10,因此,V1到V4的最短路徑為(V1,V3,V2,V4)。
那麼如何求帶權有向圖的最短路徑長度呢?可以使用迪傑斯特拉(Dijkstra)演算法。