1. 程式人生 > >資料結構,你還記得嗎(中)

資料結構,你還記得嗎(中)

2000年6月,微軟公司釋出了一種新的程式語言C#,主要由安德斯·海爾斯伯格(Anders Hejlsberg)主持開發,它是第一個面向元件的程式語言,其原始碼會編譯成msil(中間語言)再執行。
  C#是一種安全的、穩定的、簡單的、優雅的,由C和C++衍生出來的面向物件的程式語言。它在繼承C和C++強大功能的同時去掉了一些它們的複雜特性(例如沒有巨集以及不允許多重繼承)。C#綜合了VB簡單的視覺化操作和C++的高執行效率,以其強大的操作能力、優雅的語法風格、創新的語言特性和便捷的面向元件程式設計的支援成為.NET開發的首選語言。
  接下來,我會介紹C#的資料結構。

跟上一篇《資料結構,你還記得嗎(上)

》目錄進行一一對應講解C#中各種資料結構,以此來提升大家的理解。

陣列

同一型別和不同型別的多個物件

  • 同一型別多個物件
    • 可以使用集合和陣列管理。
    • C#用特殊的記號宣告、初始化和使用陣列。
    • Array類在後臺發揮作用,它為陣列中元素的排序和過濾提供了幾個方法。
    • 使用列舉器,可以迭代陣列中的所有元素。
  • 不同型別多個物件
    • 可以使用Tuple(元組)型別管理。

陣列型別

  • 一維陣列
  • 多維陣列
  • 鋸齒陣列
        多維陣列,行和列是固定的:
        int[][] arrMore=new int[3][6];

        鋸齒陣列只要在第一個方括號設定行數,每行的個數是可變的。
        int[][] jagged=new int[3][];
        jagged[0]=new int[2]{1,2};
        jagged[1]=new int[6]{1,2,3,4,5,6};
        jagged[2]=new int[3]{1,2,3};

Array

Array 類是 C# 中所有陣列的基類,它是在 System 名稱空間中定義(System.Array)。Array 類提供了各種用於陣列的屬性和方法。
用方括號宣告陣列是C#中使用Array類的表示法。在後臺使用C#語法,會建立一個派生自抽象基類Array的新類。這樣,就可以使用Array類為每個C#陣列定義的方法和屬性了。

建立陣列

  Array類是一個抽象類,所以不能使用建構函式來建立陣列。但除了可以使用C#語法建立陣列例項之外,還可以使用靜態方法CreateInstance()建立陣列。如果事先不知道元素的型別,該靜態方法就非常有用,因為型別可以作為Type物件傳遞給CreateInstance()方法。

例如:
  Array arr=Array.CeateInstance(typeof(int),5);
  for(int i=0;i<5;i++)
   { 
     arr.SetVaule(i,i);
   }
  for(int i=0;i<5;i++)
   { 
     int  vaule=arr.getVaule(i);
   }

羽毛球筒

Stack

  堆疊(Stack)代表了一個後進先出的物件集合。當您需要對各項進行後進先出的訪問時,則使用堆疊。當您在列表中新增一項,稱為推入元素,當您從列表中移除一項時,稱為彈出元素。

  • 棧以及泛型棧 
public class Stack<T> : IEnumerable<T>, ICollection, IEnumerable

public class Stack : ICollection, IEnumerable, ICloneable
屬性 描述
Count 獲取 Stack 中包含的元素個數
方法 描述
Pop public virtual object Pop();移除並返回在 Stack 的頂部的物件
push public virtual void Push(object obj);向 Stack 的頂部新增一個物件
peek public virtual object Peek();返回在 Stack 的頂部的物件,但不移除它
ToArray public virtual object[] ToArray();建立陣列並將堆疊元素複製到其中
Contains public virtual bool Contains(object obj);判斷一個元素是否在棧中
Clear public virtual void Clear();從 Stack 中移除所有的元素。

佇列

水管子

Queue

佇列(Queue)代表了一個先進先出的物件集合。當您需要對各項進行先進先出的訪問時,則使用佇列。當您在列表中新增一項,稱為入隊,當您從列表中移除一項時,稱為出隊。

  • 佇列以及泛型佇列
public class Queue : ICollection, IEnumerable, ICloneable

public class Queue<T> : IEnumerable<T>, IEnumerable, IReadOnlyCollection<T>, ICollection
屬性 描述
Count 獲取 Queue 中包含的元素個數
方法 描述
Clear public virtual void Clear(); 從 Queue 中移除所有的元素。
Contains public virtual bool Contains( object obj ); 判斷某個元素是否在 Queue 中。
Dequeue public virtual object Dequeue();移除並返回在 Queue 的開頭的物件。
Enqueue public virtual void Enqueue( object obj ); 向 Queue 的末尾新增一個物件。
ToArray public virtual object[] ToArray();複製 Queue 到一個新的陣列中。
TrimToSize public virtual void TrimToSize();設定容量為 Queue 中元素的實際個數。

連結串列

單鏈表

  • 啥是單鏈表?
     單鏈表是一種鏈式存取的資料結構,用一組地址任意的儲存單元存放線性表中的資料元素。這組儲存單元既可以是連續的,也可以是不連續的。
     連結串列中的資料是以結點來表示的,每個結點的構成:元素(資料元素的映象) + 指標(指示後繼元素儲存位置),元素就是儲存資料的儲存單元,指標就是連線每個結點的地址資料。
  • 連結串列的結點結構
    ┌───┬───┐
    │data│next │
    └───┴───┘
     data域--存放結點值的資料域[元素]
     next域--存放結點的直接後繼的地址(位置)的指標域(鏈域)[指標]
實現方式
public class Node<T>
{
    public T Data { set; get; }          //資料域,當前結點資料
    public Node<T> Next { set; get; }    //位置域,下一個結點地址

    public Node(T item)
    {
        this.Data = item;
        this.Next = null;
    }

    public Node()
    {
        this.Data = default(T);
        this.Next = null;
    }
}

請轉到《資料結構:單鏈表》檢視更詳細內容!

雙向連結串列

  LinkedList 是一個雙向連結串列,其元素會指向它前面和後面的元素。這樣,通過移動到下一個元素可以正向遍歷連結串列,通過移動到前一個元素可以反向遍歷連結串列。

連結串列在儲存元素時,不僅要儲存元素的值,還必須儲存每個元素的下一個元素和上一個元素的資訊。這就是LinkedList 包含LinkedListNode 型別的元素的原因。使用LinkedListNode ,可以獲得列表中的下一個和上一個元素。LinkedListNode 定義了屬性List,Next,Previous和Value。List屬性返回與節點相關的LinkedList 物件。Next和Previous屬性用於遍歷連結串列,訪問當前節點之後和之前的節點。Value屬性返回與節點相關的元素,其型別是T。
  連結串列的優點是,如果將元素插入到列表的中間位置,使用連結串列就會很快。在插入一個元素時,只需要修改上一個元素的Next引用和下一個元素的Previous引用,使它們引用所插入的元素。在List 中,插入一個元素,需要移動該元素後面的所以元素。
  連結串列的缺點是,連結串列元素只能一個接一個的訪問,這需要較長時間來查詢位於連結串列中間或尾部的元素。
LinkedList 類定義的成員可以訪問連結串列中的第一個和最後一個元素(First和Last);
  在指定位置插入元素:AddAfter(),AddFirst()和AddLast();
  刪除指定位置的元素:Remove(),RemoveFirst(),RemoveLast();
  搜尋:Find(),FindLast()。


選單樹

C#中沒有實現樹的具體類,一般可以通過自己實現。
結點樹包含:父結點(根結點的父結點為null)、子結點(List集合)、資料物件。

請轉到《 資料結構:樹》檢視更詳細的內容!


  圖狀結構簡稱圖,是另一種非線性結構,它比樹形結構更復雜。樹形結構中的結點是一對多的關係,結點間具有明顯的層次和分支關係。每一層的結點可以和下一層的多個結點相關,但只能和上一層的一個結點相關。而圖中的頂點(把圖中的資料元素稱為頂點)是多對多的關係,即頂點間的關係是任意的,圖中任意兩個頂點之間都可能相關。也就是說,圖的頂點之間無明顯的層次關係,這種關係在現實世界中大量存在。因此,圖的應用相當廣泛,在自然科學、社會科學和人文科學等許多領域都有著非常廣泛的應用。

c#沒有實現圖的資料結構,但是可以自己實現,參考如下
請轉到《資料結構:圖》檢視更詳細內容!


字典樹

c#也沒有實現字典樹,可以自己實現,參考如下

請轉到《資料結構:字典樹》檢視更詳細內容!


散列表(雜湊表)

雜湊表(HashTable)簡述

  Hashtable是System.Collections名稱空間提供的一個容器,用於處理和表現類似keyvalue的鍵值對,其中key通常可用來快速查詢,同時key是區分大小寫;value用於儲存對應於key的值。Hashtable中keyvalue鍵值對均為object型別,所以Hashtable可以支援任何型別的keyvalue鍵值對.

什麼情況下使用雜湊表

  • 某些資料會被高頻率查詢
  • 資料量大
  • 查詢欄位包含字串型別
  • 資料型別不唯一

使用方法

  • 雜湊表需要使用的namespace
using System.Collections;
using System.Collections.Generic;
  • 雜湊表的基本操作:
//新增一個keyvalue鍵值對:
HashtableObject.Add(key,value);

//移除某個keyvalue鍵值對:
HashtableObject.Remove(key);

//移除所有元素:           
HashtableObject.Clear(); 

// 判斷是否包含特定鍵key:
HashtableObject.Contains(key);
  • 遍歷雜湊表
 遍歷雜湊表需要用到DictionaryEntry Object,程式碼如下:
for(DictionaryEntry de in ht) //ht為一個Hashtable例項
{
   Console.WriteLine(de.Key);  //de.Key對應於keyvalue鍵值對key
   Console.WriteLine(de.Value);  //de.Key對應於keyvalue鍵值對value
}

請轉到《資料結構:雜湊表》檢視更詳細內容!


總結

綜上所述,找了相關的文件之後,發現C#本身沒有封裝部分資料結構,可能是讓大家自己發揮,也可能跟它當初設計的原因有關,因為它不是專們為處理資料而誕生的。真的又是寫了一篇小白文,發現寫到這裡還不夠,於是將標題改為《資料結構,你還記得嗎(中)》,接下來還要繼續《資料結構,你還記得嗎(下)》 未完待續!

其他系列的C#資料結構參考《C# 資料結構