1.資料結構學習之線性表(一)
開篇:資料結構是程式應用裡基礎的學科。 官方來說,資料結構是計算機儲存、組織資料的方式。
資料結構有著非常重要的重用,如果理解並且掌握它,在我們的學習或者工作中的開發會事半功倍。
接下來,開始我們的資料結構學習之路吧。(程式碼為C#形式)
1.什麼是線性表?
線性表是最基本、最簡單、也是最常用的一種資料結構。例如我們開發中最常用的關係型資料庫。
例如這張學生表。
學號 | 姓名 | 性別 | 年齡 |
1 | 阿黃 | 男 | 22 |
2 | 阿虎 | 女 | 23 |
3 | 阿蛋 | 男 | 24 |
在這張學生表中,這裡的表為典型的線性表,由a1,a2......an組成的有限序列,在這張表中有3個數據元素,也稱紀錄,(學校,姓名..)這些稱為資料項。
由此可見:線性表有如下特徵:
1.有且僅有一個為開始元素的(在這裡,阿黃是首個開始資料),它沒有前趨,僅有一個後繼元素(這裡為阿虎)。
2.有且僅有一個為結束元素的(在這裡,阿蛋是結束資料),它沒有後繼,僅有一個直接前趨勢(這裡為阿虎)。
3.除去首尾的兩個元素,其餘的為內部元素,有且僅有一個直接前趨勢和直接後繼元素(這裡為阿虎)。
2.線性表的基本運算?
對於線性表,有這幾種基本的運算:
1.增加元素 。2.查元素 。3.插入元素。4.刪除元素等等。
接下來我會使用C# 來構建一個最基本的線性表型別(陣列),大家也可以使用自己的語言來改寫。
3.程式碼片段
我們先新增個Array類,初始化的時候我們預設給容量Capacity為20。
public class Array { private int[] Data; private int Size; private readonly int Capacity; public bool IsFull => this.Capacity == this.Size; public Array(int capacity = 20) { this.Capacity = capacity; this.Data = new int[this.Capacity]; } }
Add方法在末尾新增元素。判斷是否容量已滿。滿了就報了異常。加成功了,Size就會+1
1 public void Add(int value) 2 { 3 if (IsFull) 4 throw new Exception("Array is full"); 5 this.Size++; 6 this.Data[this.Size - 1] = value; 7 }
Insert方法在特定位置插入元素。
例如這張,此時5要插入到這個數組裡,插入成功後應為1,2,5,3,4。長度Size會增加。
程式碼如下:只要迴圈當前插入的元素到陣列長度。每一個都往後移動一位即可。插入之前的資料不動。
public void Insert(int index,int value) { if (index < 0) throw new Exception("indexis less than zero"); if (index > this.Capacity-1 || index > this.Size) throw new Exception("index is more than capacity or Size"); for (int i = Size-1; i >index-1; i--) { this.Data[i + 1] = this.Data[i]; } this.Data[index] = value; this.Size++; }
Delete方法在刪除元素。
1.根據索引刪除元素,與插入類似,刪除當前索引的值,後面的元素應全部往前移動一格。最後一為元素應置為空,長度Size也應減1。
1 public void Delete(int index) 2 { 3 if (index < 0) 4 throw new Exception("index is less than zero"); 5 if (index > this.Capacity-1) 6 throw new Exception("index is more than capacity"); 7 if (index > this.Size-1) 8 return; 9 for (int i = index; i < this.Size-1; i++) 10 { 11 this.Data[i] = this.Data[i+1]; 12 } 13 this.SetEmpty(this.Size-1); 14 this.Size--; 15 } 16 17 private void SetEmpty(int index) 18 { 19 this.Data[index] = default; 20 }
2.刪除某個元素值,查詢到這個值所在的索引,再去刪除他。
public void DeleteElement(int value) { var eleIndex = -1; for (int i = 0; i < this.Size; i++) { if (this.Data[i] == value) eleIndex = i; } if (eleIndex < 0) return; this.Delete(eleIndex); }
跟新元素,這個嘛,比較簡單。
1 public void Update(int index,int value) 2 { 3 if (index < 0) 4 throw new Exception("index is less than zero"); 5 if (index > this.Capacity - 1) 6 throw new Exception("index is more than capacity"); 7 if (index > this.Size - 1) 8 return; 9 this.Data[index] = value; 10 }
常規判斷,判斷資料是否存在,查詢方法等等。
1 public bool IsContain(int value) 2 { 3 var isContain = false; 4 for (int i = 0; i < this.Size; i++) 5 { 6 if (this.Data[i] == value) 7 isContain = true; 8 } 9 return isContain; 10 } 11 12 public int Find(int value) 13 { 14 for (int i = 0; i < this.Size; i++) 15 { 16 if (this.Data[i] == value) 17 return i; 18 } 19 return -1; 20 } 21 22 public int Search(int index) 23 { 24 if(index>Size-1 || index<0) 25 throw new Exception("this index is empty or index is less than zero"); 26 return this.Data[index]; 27 } 28 29 public override string ToString() 30 { 31 var list = new List<int>(); 32 for (int i = 0; i < this.Size; i++) 33 { 34 list.Add(this.Data[i]); 35 } 36 return $"Use {this.Size}, Capacity {this.Capacity} Numbers is {string.Join(",", list.Select(i => i))}"; 37 }
寫到這裡。我們基本的寫好了一個最簡單的陣列線性表。但有沒有發現,我們寫的這種結構侷限性很大,比如他只支援int呀,我們肯定想支援各種型別。
而且我們此時的各中方法效能又如何呢,算句話說我們的空間複雜度又是如何的呢,容量問題又如何解決呢。我們下一章再來優化和改善這一陣列結構。謝謝大家~~~~~~
&n