標籤:
線性表
線性表是最簡單、最基本、最常用的資料結構。資料元素 1 對 1的關係,這種關係是位置關係。
特點
(1)第一個元素和最後一個元素前後是沒有資料元素,線性表中剩下的元素是近鄰的,前後都有元素。
(2)線性表中的元素是有限的(List),線性表中的資料類型一致。
(3)線性表表示方法 L={a1,a2,a3,a4…….an},L=(D,R)
(4)每一個元素都有前驅和後繼,第一個元素只有後繼,最後一個元素只有前驅。
執行個體
例如:1~100的整數是一個線性表
{“zhangsan”, “lisi”, “wangwu”}
……
A.順序表
所有的操作都是根據建立線上性結構的基礎之上進行的,線性表介面表示如下:
public interface IListDS<T>
{
int GetLength(); //求長度
void Clear();//清空線性表
bool IsEmpty();//判斷是否為空白
void Append(T item);//追加元素
void Insert(T item,int i);//插入元素
T Delete(int i);//刪除元素
T GetElem(int i);//擷取元素
int Locate(T value);//尋找元素
void Reverse();//倒置
}
操作
1.插入操作:
30在插入之前資料表沒有什麼變化,當30資料出入到第i個位置後,後面的資料需要向後移動,那麼插入的
資料越靠前,所需要移動的次數越多,如果i=0 那麼需要向後移動 n 個位置,如果插入到最後一個,那麼
順序表就不需要移動,如果插入的資料的位置i的機率為Pi,那麼需要移動的位置次數為n/2,在順序表中移動
其中一半的資料,那麼插入操作的時間複雜度為0(n)。
2.刪除操作:順序表刪除操作和插入操作一致,時間都是浪費在移動資料上,時間複雜度也為0(n)
3.讀取操作:直接讀取到順序表中的數值 比如 IListDS[i]元素,那麼時間複雜度為 0(1) 只需要取一次即可。
4.尋找操作:尋找需要找到資料位元置i,然後判斷數值是否一致,這個類似於插入和刪除,時間複雜度:0(n)
5.倒置操作:倒置操作只需要把前後對比 把第i個元素和第n-i個元素交換即可,時間複雜度也為:0(n)
B.單鏈表
對比順序表,邏輯相同的資料在物理地址上也相同,在順序表上尋找一個位置上的資料非常方便,這是順序表的
優勢所在,那麼問題來了,在順序表插入或者刪除一個資料時候往往需要移動剩下的資料,那麼這樣會影響效率
,接下來學習一下線性表的另外一個儲存結構----鏈式儲存(Linked Strorage),這樣的線性表叫做(Linked
List),對單鏈表的操作也不需要移動其他資料元素,但也失去順序表可隨機儲存的優點。
從兩張圖我們可以看到單鏈表的結構和順序表的一個差異
單鏈表實現的方法:
pulic class LinkedList<T>:IListDS<T>
{
Pulic Node<T> Head;//屬性
pulic LinkedList();//構造器
pulic GetLength();//擷取長度
pulic Clear();//清空
pulic bool IsEmpty();//判斷是否為空白
pulic void Append(T item);//追加
pulic void Insert(T item,int i);//i位置插入
pulic void Delete(T item);//刪除元素
pulic T GetElem(int i);//擷取單鏈表第i個元素
pulic int i Location(T item);//尋找位置
pulic void Reserver();//倒置
}
操作
1.擷取長度
單鏈表和順序表的長度過去方法不一致,因為單鏈表是連續的順序空間,而單鏈表
從頭引用頭開始,一個節點一個節點的便利,直到表的末尾。那麼問題來了:剛剛介紹單鏈表物理空間不也是
連續的嗎?這個筆者個人理解,初始化資料是物理連續,而新插入的資料不會按照物理地址排列,所以所單鏈
表還是要便利整個內容來計算長度,時間複雜度為 0(n)。
2.清空操作
清空操作是指將單鏈表所有的節點使得單鏈表為空白,此時頭引用head為null.清空單鏈表的演算法實現如下:
pulic void Clear()
{
head=null;
}
需要注意的是,單鏈表清空後,原來節點所佔用的空間不會一直保留,而由記憶體回收行程進行回收和順序表不一樣
的是,順序表是連續的空間,數組分配的空間仍然保留。
3.附加操作
附加操作,是要便利單鏈表中所有的元素,然後在鏈表的尾部添加元素,時間複雜度為:0(n);
線性表的順序儲存和鏈式儲存各有優缺點,線性表如何儲存取決於使 用的場合。如果不需要經常線上性表中進行
插入和刪除,只是進行尋找,那麼, 線性表應該順序儲存;如果線性表需要經常插入和刪除,而不經常進行尋找
,則 線性表應該鏈式儲存。
C 結合單向鏈表,肯定也有有雙向鏈表,雙向鏈表也是有上面的基本操作,然後思考相關的問題:時間複雜度問題。
D 迴圈列表:迴圈鏈表是在單鏈表和雙向鏈表的基礎上頭尾相連Last.Next=>Header.Head
C#中的線性表
說道C# 線性表那就是List,在1.1中提供了非泛型介面 IList,介面中的項是object,非泛型IList是從ICollection
介面繼承而來,是所有線性表的介面,用了這麼長時間的List才發現IList是線性結構,IList分為三類:唯讀,大
小不可變,大小可變的。
唯讀IList:不能被修改,插入或者刪除。
大小不變的IList:不能在表中插入或刪除,但是可以修改表中的項。
大小可變的ILIST: 可以操作,可以插入或者刪除
非泛型的IList介面聲明如下:
interface IList:ICollenciton,IEnumberable
{
//共有屬性
bool IsFiexedSize{get;} //唯讀,如果IList有固定大小
bool IsReadOnly{get;} //唯讀 ,如果ILIST是唯讀
object this[T index] {get;set;} //索引器 得到某個類型
int add(object value);
void clear();
int indexof(object value);
bool contains(ojbject value);
void insert(index,object value);
void remove();
void removeat();
}
.NET 架構中一些集合實現了IList介面,如ArrayList,ListDictionary,StringCollection,String Dictionary.
.NET 線性表中順序儲存採用的是數組,而鏈式的儲存方式則是:IList介面。
未完待續…….
C# 資料結構 線性表(順序表 鏈表 IList 數組)