資料結構與演算法之線性表

2022-05-28 21:09:11 字數 3285 閱讀 3960

線性表屬於資料結構中邏輯結構中的線性結構。回憶一下,資料結構分為物理結構和邏輯結構,邏輯結構分為線性結構、幾何結構、樹形結構和圖形結構四大結構。其中,線性表就屬於線性結構。剩餘的三大邏輯結構今後會一一介紹。

線性表(list):由零個或多個資料元素組成的有限序列。

注意:1.線性表是乙個序列。

2.0個元素構成的線性表是空表。

3.線性表中的第乙個元素無前驅,最後乙個元素無後繼,其他元素有且只有乙個前驅和後繼。

4.線性表是有長度的,其長度就是元素個數,且線性表的元素個數是有限的,也就是說,線性表的長度是有限的。

若將線性表記為(a1,…,ai-1,ai,ai+1,…an),則表中ai-1領先於ai,ai領先於ai+1,稱ai-1是ai的直接前驅元素,ai+1是ai的直接後繼元素。

initlist(*l): 初始化操作,建立乙個空的線性表l。

listempty(l): 判斷線性表是否為空表,若線性表為空,返回true,否則返回false。

clearlist(*l): 將線性表清空。 getelem(l,i,*e): 將線性表l中的第i個位置元素值返回給e。

listdelete(*l,i,*e): 刪除線性表l中第i個位置元素,並用e返回其值。

listlength(l): 返回線性表l的元素個數。

對於不同的應用,線性表的基本操作是不同的,上述操作是最基本的。

對於實際問題中涉及的關於線性表的更複雜操作,完全可以用這些基本操作的組合來實現。

我們知道,資料結構分為邏輯結構和物理結構,邏輯結構分為集合結構、線性結構、樹形結構和圖形結構四大類。物理結構分為順序儲存結構和鏈式儲存結構。我在之前寫的《資料結構和演算法》中已經介紹過。

線性表是線性結構的一種,那麼線性表當然也有物理結構,也就是說,線性表有兩種,分別是順序結構的線性表(叫做順序表)和鏈式結構的線性表(叫做鍊錶)。

順序表是指順序儲存結構的線性表,指的是用一段位址連續的儲存單元依次儲存線性表的資料元素。

順序表表現在物理記憶體中,也就是物理上的儲存方式,事實上就是在記憶體中找個初始位址,然後通過佔位的形式,把一定的記憶體空間給佔了,然後把相同資料型別的資料元素依次放在這塊空地中。注意,這塊物理記憶體的位址空間是連續的。

舉 個例子,比如c語言中的基本變數的儲存就是連續的儲存在記憶體中的,比如宣告乙個整數i,在64位系統中整數i在記憶體中佔8位元組,那麼系統就會在記憶體中為這 個整型變數分配乙個長度為8個位元組的連續的位址空間,然後把這個i的二進位制形式從高位址向低位址儲存,長度不足時候,最高位用0補齊。

順序表的結構體定義

#define maxsize 20  // 順序表的最大儲存容量

typedef int elemtype; // 順序表儲存的資料型別

typedef struct sqlist;

通過上面用結構體定義順序表,我們可以看出順序表的封裝需要三個屬性:

1.儲存空間的起始位置。陣列data的儲存位置就是線性表儲存空間的儲存位置

2.線性表的最大儲存容量。陣列長度maxsize

3.線性表的當前長度。length

注意:陣列的長度與線性表的當前長度是不一樣的。陣列的長度是存放線性表的儲存空間的總長度,一般初始化後不變。而線性表的當前長度是線性表中元素的個數,是會改變的。

順序表查詢元素操作

**實現:

順序表插入元素操作

思路如下:

1.如果插入位置不合理,丟擲異常;

2.如果線性表長度大於等於陣列長度,則丟擲異常或動態增加陣列容量;

3.從最後乙個元素開始向前遍歷到第i個位置,分別將它們都向後移動乙個位置;

4.將要插入元素填入位置i處;

5.線性表長+1。

**實現:

順序表刪除元素操作

思路如下:

1.如果刪除元素的位置不合理,丟擲異常。比如使用者刪除第0個位置的元素(線性表是從1開始的)、刪除元素的位置大於線性表的長度也要丟擲異常。

2.刪除第i個位置的元素。

3.把第i個位置的元素後面的所有的元素的位置加一。

4.線性表長度減一。

**實現:

由以上**可以看出:

線性表的順序儲存結構,在存、讀取資料時,不管是在哪個位置,時間複雜度都是o(1)。而在插入或者刪除時,時間複雜度都是o(n)。

這也就是線性表的順序儲存結構比較適合訪問資料,不適合經常插入和刪除資料的應用。

優點:1.無需為了表示表中元素之間的邏輯關係而增加額外的儲存空間(相對於鏈式儲存而言)。

2.可以快速的訪問表中任意位置的元素。

缺點:1.插入和刪除操作需要移動大量的元素。

2.當線性表長度變化較大時,難以確定儲存空間的容量。

3.容易造成儲存空間的「碎片」(因為線性表的順序儲存結構申請的記憶體空間都以連續的,如果因為某些操作(比如刪除操作)導致某個部分出現了一小塊的不連續記憶體空間,因為這一小塊記憶體空間太小不能夠再次被利用/分配,那麼就造成了記憶體浪費,也就是「碎片」)

ps:windows系統有磁碟碎片整理工具,而linux系統沒有,因為linux系統核心優化的很好,幾乎是沒有磁碟碎片的。

前面我們講的線性表的順序儲存結構,它最大的缺點就是插入和刪除時需要移動大量元素,這顯然就需要耗費時間。

那我們能不能針對這個缺陷或者說遺憾提出解決的方法呢?要解決這個問題,我們就得考慮一下導致這個問題的原因!

為什麼當插入和刪除時,就要移動大量的元素?

原因就在於相鄰兩元素的儲存位置也具有鄰居關係,它們在記憶體中的位置是緊挨著的,中間沒有間隙,當然就無法快速插入和刪除。

線性表的鏈式儲存結構的特點是用一組任意的儲存單元儲存線性表的資料元素,這組儲存單元可以存在記憶體中未被占用的任意位置。

也就是說,鏈式儲存結構的線性表由乙個(可以使零)或者多個結點(node)組成。每個節點內部又分為資料域和指標域(鏈)。資料域儲存了資料元素的資訊。指標域儲存了當前結點指向的直接後繼的指標位址。

因為每個結點只包含乙個指標域,所以叫做單鏈表。顧名思義,當然還有雙鏈表。

單鏈表鏈式儲存結構中,除了要儲存資料元素資訊外,還要儲存它的後繼元素的儲存位址(指標)。

也就是說除了儲存其本身的資訊外,還需儲存乙個指示其直接後繼的儲存位置的資訊。

我們把儲存資料元素資訊的域稱為資料域,把儲存直接後繼位置的域稱為指標域。

指標域中儲存的資訊稱為指標或鏈。

這兩部分資訊組成資料元素稱為儲存映像,或稱為結點(node)。

n個結點鏈結成乙個鍊錶,即為線性表(a1, a2, a3, …, an)的鏈式儲存結構。

因為此鍊錶的每個結點中只包含乙個指標域,所以叫做單鏈表。

對於線性表來說,總得有個頭有個尾,鍊錶也不例外。我們把鍊錶中的第乙個結點的儲存位置叫做頭指標,最後乙個結點指標為空(null)。

資料結構與演算法之線性表

1.線性表的基本概念 線性表是零個或多個資料元素的有序佇列.特性 資料元素之間是有順序的 資料元素個數是有限的 資料元素的型別必須相同.2.線性表的數學定義及性質 線性表是具有相同型別的n n 0 個資料元素的有限序列 a0,a1,a2.an ai是表項,n是表長度.性質 a0是線性表中的第乙個元素...

資料結構與演算法之 線性表

01線性表 1.線性表的判斷方式就是元素有且只有乙個直接前驅和直接後繼,元素可以為空,此時叫做空表 2.抽象資料型別標準格式 adt 抽象資料型別名 data operation endadt 3.操作偽 operation endadt 4.實際問題 提問 實現兩個線性表a,b的並集操作 思路 迴...

資料結構與演算法分析之線性表

最近面試了不少公司,發現多數公司要提問資料結構與演算法分析,所以這段期間又簡單回顧了下資料結構與演算法。列表內容 簡單來說呢程式 資料結構 演算法只不過是實現的語言不同而已,有人說,學習資料結構沒一點用,工作中一點用也沒有,這點仁者見仁智者見智,現在的大部分公司是業務為王,業務理解透了,能幹就幹,幹...