資料結構筆記 線性表定義與實現(Swift)

2021-09-11 13:34:05 字數 4302 閱讀 3739

資料結構筆記系列 資料結構筆記—兩個有序鍊錶合併成乙個有序鍊錶

線性表是最常用且最簡單的一種資料結構,簡言之,乙個線性表是 n 個資料元素的有序序列.

只有乙個首結點和尾結點;

除首尾結點外,其他結點只有乙個直接前驅和乙個直接後繼。

簡言之,線性結構反映結點間的邏輯關係是 一對一的, 線性結構包括線性表、堆疊、佇列、字串、陣列等等,其中,最典型、最常用的

從儲存結構上來劃分,可分為順序儲存結構稱順序表和鏈式儲存結構稱鍊錶

順序表的儲存定義

把邏輯上相鄰的資料元素儲存在物理上相鄰的儲存單元中的儲存結構。簡單來說,邏輯上相鄰,物理上也相鄰

順序表的特點:

利用資料元素的儲存位置表示線性表中相鄰資料元素之間的前後關係,即線性表的邏輯結構與儲存結構一致

在訪問線性表時,可以快速地計算出任何乙個資料元素的儲存位址。因此可以粗略地認為,訪問每個元素所花時間相等 

順序表的複雜度:

時間複雜度:順序表的查詢、插入、刪除演算法的平均時間複雜度為o(n)

空間複雜度:順序表的時間複雜度為o(1)

順序表的優缺點:

優點:儲存密度大(結點本身所佔儲存量/結點結構所佔儲存量) 可以隨機訪問表中任一元素

缺點:在插入、刪除某一元素時,需要移動大量元素 浪費儲存空間 屬於靜態儲存形式,資料元素的個數不能自由擴充

鍊錶的特點

結點在儲存器中的位置是任意的,即邏輯上相鄰的資料元素在物理上不一定相鄰線性表的鏈式表示又稱為非順序映像或鏈式映像。

結點

資料元素的儲存映像。由資料域和指標域兩部分組成.資料域:儲存元素數值資料.指標域:儲存直接後繼結點的儲存位置

注意: ==頭指標,頭結點,首元結點==這幾個概念:

頭結點可以有也可以沒有,但是頭指標必須要有。

單鏈表
結點只有乙個指標域的鍊錶。每個結點中除了包含資料域以外還包含乙個指標域,用於指向其後繼結點。

單鏈表的儲存映像

單鏈表的實現

單鏈表是否為空

func isempty() -> bool 

複製**

獲取首元結點
public var first:node?

複製**

獲取尾結點
public var last:node? 

return node

} else

}複製**

鍊錶的長度
public var count:int 

return c

} else

}複製**

結點的獲取
func getnode(atindex index:int) -> node? 

i -= 1

node = node?.next}}

return nil

}複製**

鍊錶的新增

let newnode = slnode(value: value)

iflet lastnode = last else

}// 批量新增

for value in values

}複製**

鍊錶的插入 插入在第 index 結點

public func insertnode(atindex index:int,value:t)  else 

} else

if (index == 0 ) else

}複製**

單鏈表刪除

刪除在某乙個 位置的結點

public func removenode(atindex index:int)

}// 刪除所有結點

public func removeall

() 複製**

雙鏈表

有兩個指標域的鍊錶。雙鏈表就是在單鏈表上增加乙個指標域,指向當前結點的前驅.用於方便地找到其前驅結點.和單鏈表類似也分為帶頭結點的雙鏈表和不帶頭結點的雙鏈表.

雙向鍊錶的實現

定義乙個雙向鍊錶的結點

//定義乙個 結點 雙向鍊錶的結點定義格式

public class dlnode

}複製**

定義乙個雙向鍊錶
public final class doublelinklist

}複製**

雙向鍊錶是否為空
public var isempty:bool 

複製**

雙向鍊錶獲取首元結點
public var first:node?

複製**

雙向鍊錶獲取尾結點

尾結點的next 指標指向的結點必定為空。所以從首結點開始遍歷,如果 next 為空比為尾結點

public var last:node? 

return node

} else

}複製**

雙向鍊錶的長度

從首元結點開始遍歷,一直遍歷到尾結點,直到遍歷完成,每有乙個結點長度加一

public var count:int 

return c

} else

}複製**

雙向鍊錶的查詢:

從首元結點開始相後查詢 複雜度為 o(n)

public func node(atindex index: int) -> node? 

i -= 1

node = node!.next}}

return nil

}複製**

雙向鍊錶的插入

在某個位置插入乙個結點。雙向鍊錶的插入步驟;

public func insert(_ node: node, atindex index: int) 

}複製**

雙向鍊錶的刪除

刪除鍊錶中某乙個結點,步驟如下

@discardableresult public func remove(atindex index: int) -> t 

@discardableresult public func remove(node: node) -> t else

next?.previous = prev

node.previous = nil

node.next = nil

return node.value

}複製**

雙向鍊錶翻轉
public func reverse

() }

複製**

查詢: 因線性鍊錶只能順序訪問,即在查詢時要從頭指標找起,查詢的時間複雜度為 o(n)。

插入和刪除: 因線性鍊錶不需要移動元素,只要修改指標,一般情況下時間複雜度為 o(1)。

但是,如果要在單鏈表中進行前插或刪除操作,由於要從頭查詢前驅結點,所耗時間複雜度為 o(n) 。

迴圈單鏈表

單鏈表的最後乙個指標域指向鍊錶中的第乙個結點即可。迴圈單鏈表可以以實現從任何乙個結點出發訪問鍊錶中的任何結點。

迴圈雙鏈表

首尾相接的鍊錶,源自於雙鏈表。即將終端結點的後繼結點設為第乙個結點(首元結點或者頭結點)將鍊錶中的第乙個結點的前繼結點設為終端結點。

資料元素的個數可以自由擴充

插入、刪除等操作不必移動資料,只需修改鏈結指標,修改效率較高

儲存密度小

訪問效率不高,必須採用順序訪問,即訪問資料元素時,只能按鍊錶的順序進行訪問(順藤摸瓜)

基於空間的比較

儲存分配方式:順序表的儲存空間是靜態分配的,鍊錶的儲存空間是動態分配的

儲存密度:(儲存密度= 結點值域所佔的儲存量/結點結構所佔的儲存總量),順序表的儲存密度 = 1 鍊錶的儲存密度 < 1 (因為結點中儲存的有指標域)

基於時間的比較:

訪問方式:順序表可以隨機訪問,也可以順序訪問,鍊錶是順序訪問

插入刪除時移動的元素的個數:順序表平均需要移動近一半的元素,鍊錶不需要移動,只需要修改指標

更多詳細**

資料結構筆記 線性表

思考 怎麼程式設計解決多項式相加問題?1.線性表概念 由同型別資料元素構成的有序序列的線性結構 1.表中元素個數稱為線性表的長度 2.線性表中沒有元素時稱為空表 3.表的起始位置稱為表頭,結束位置稱為表尾。2.線性表的adt描述 3.線性表的順序儲存實現 未測試 include using name...

資料結構筆記 線性表

資料元素的資料型別。struct seqlist seqlist sl create int maxlen void sl free seqlist slist 釋放 刪除 順序表。與sqlst create 配對。void sl makeempty seqlist slist 置為空表。intsl...

資料結構 筆記 線性表

定義 由同型別資料元素構成有序序列的線性結構 型別名稱 list 物件集 n n 0 個元素構成的有序序列 操作集 list makeempty 初始化乙個空線性表l elementtype findkth int k,list l 根據位序k,返回相應元素 int find elementtype...