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

數據結構,你還記得嗎(中)

font 鏈式 ray 排序 所有 reat 分享 就會 實例

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# 數據結構》

數據結構,你還記得嗎(中)