1. 程式人生 > >1.資料結構學習之線性表(一)

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