資料結構中的線性表及其結構
線性表(linear list) )
線性表是n個型別相同資料元素的有限序列,通常記作(a 0 , a 1 , …a i-1 , a i , a i+1 …,a n-1 )。
1.相同資料型別
線上性表的定義中,我們看到從a 0 到a n-1 的n個數據元素是具有相同屬性的元素。
比如說可以都是數字,例如(23, 14, 66, 5, 99);
也可以是字元,例如(A, B, C, … Z);
當然也可以是具有更復雜結構的資料元素,例如學生、商品、裝備。
相同資料型別意味著在記憶體中儲存時,每個元素會佔用相同的記憶體空間,便於後續的查詢定位。
2.序列(順序性)
線上性表的相鄰資料元素之間存在著序偶關係,
即a i-1 是a i 的直接前驅,則a i 是a i-1 的直接後續,
同時a i 又是a i+1 的直接前驅,a i+1 是a i 的直接後續。
唯一沒有直接前驅的元素a 0 一端稱為表頭,
唯一沒有後續的元素a n-1 一端稱為表尾。
除了表頭和表尾元素外,任何一個元素都有且僅有一個直接前驅和直接後繼。
3.有限
線性表中資料元素的個數n定義為線性表的長度,n是一個有限值。
當n=0 時線性表為空表。
在非空的線性表中每個資料元素線上性表中都有唯一確定的 序號, 例如a 0 的序號是 0,a i 的序號是i。
在一個具有n > 0 個數據元素的線性表中,資料元素序號的範圍是[0, n-1]。
生活案例:冰糖葫蘆、多個學生分數、多個學生資料
線性表的邏輯結構
具體描述參看上面線性表的定義
線性表的儲存結構
1.順序表----順序儲存結構
特點:在記憶體中分配連續的空間,只儲存資料,不需要儲存地址資訊。位置就隱含著地址。
優點:節省儲存空間;
按照索引查詢效率高
假設線性表的每個資料元素需佔用K個儲存單元,並以元素所佔的第一個儲存單元的地址作為資料元素的儲存地址。
則線性表中序號為i的資料元素的儲存地址LOC(a i )與序號為i+1 的資料元素的儲存地址LOC(a i+1 )之間的關係為
LOC(a i+1 ) = LOC(a i ) + K
通常來說,線性表的i號元素a i 的儲存地址為
LOC(a i ) = LOC(a 0 ) + i×K
其中LOC(a 0 )為 0 號元素a 0 的儲存地址,通常稱為線性表的起始地址。
缺點:
刪除、新增需要大量移動元素,效率低;
按照內容查詢元素,需要逐個比較判斷,效率低下。
如果初始分配空間大,實際儲存元素少,也會導致空間的浪費
舉例:長度為n的陣列中刪除元素,假設每個元素刪除的概率是相同的,問時間複雜度是?
刪掉第n個元素,需要移動0個元素
刪掉第n-1個元素,需要移動1個元素
刪掉第n-2個元素,需要移動2個元素
....
刪掉第2個元素,需要移動n-2個元素
刪掉第1個元素,需要移動n-1個元素
所以平均時間頻度是:0*1/n + 1*1/n + 2*1/n + 3*1/n + + (n-1)*1/n = (n-1)*n/2 * 1/n = (n-1)/2
T(n) = (n-1)/2
T(n)= O(n)
2.連結串列----鏈式儲存結構
特點:在記憶體中分配不連續的空間,每個元素節點中,專門增加了空間來儲存下個元素的地址。最後一個節點的地址值為null 。
優點:刪除、新增不需要移動元素,效率高。(但是需要先定位到元素上)
缺點:每個元素節點中,專門增加了空間來儲存下個元素的地址,佔用更多空間。
每個節點地址不連續、無規律,導致按照索引查詢效率低下。線性表的操作
/**
* 線性表介面
* @author Administrator
*
*/
public interface List {
// 返回線性表的大小,即資料元素的個數。
public int size();
// 返回線性表中序號為 i 的資料元素
public Object get(int i);
// 如果線性表為空返回 true,否則返回 false。
public boolean isEmpty();
// 判斷線性表是否包含資料元素 e
public boolean contains(Object e);
// 返回資料元素 e 線上性表中的序號
public int indexOf(Object e);
// 將資料元素 e 插入到線性表中 i 號位置
public void add(int i, Object e);
// 將資料元素 e 插入到線性表末尾
public void add(Object e);
// 將資料元素 e 插入到元素 obj 之前
public boolean addBefore(Object obj, Object e);
// 將資料元素 e 插入到元素 obj 之後
public boolean addAfter(Object obj, Object e);
// 刪除線性表中序號為 i 的元素,並返回之
public Object remove(int i);
// 刪除線性表中第一個與 e 相同的元素
public boolean remove(Object e);
// 替換線性表中序號為 i 的資料元素為 e,返回原資料元素
public Object replace(int i, Object e);
}