最全的資料結構解析與歸納

gb4215287發表於2017-09-30

本文對常用的資料結構:Array, ArrayList,List,IList,ICollection, Stack, Queue, HashTable, Dictionary, IQueryable, IEnumerable等進行詳述。


一、Collection(集合)
Collection是資料記錄集合,編寫程式碼過程中,常常需要合適的容器儲存臨時資料,方便修改和查詢,如何選取合適的資料容器,關鍵在於將執行的資料操作以及資料記錄是否大量。


二、Array(陣列)

特徵

1. 固定大小,陣列的大小是初始化時決定無法修改的數值。

2. 強型別,儲存資料元素型別必須在初始化時指定,因此在執行時,不需要耗費額外的時間來定義陣列型別,能夠大大提升執行效率。

3. 可使用Foreach關鍵字實現陣列迭代和查詢。

因為陣列大小是固定的,且是強型別資料結構,因此在執行時只佔用很少的記憶體,執行時效率很高。


三、ArrayList

1. ArrayList 沒有固定的長度,容量可動態增加,可應用於開發人員無法確定陣列元素個數等場景,當然這種情況下,在定義結構體的時候會非常耗時。

2. ArrayList 不是強型別,ArrayList中不同元素型別可以不相同,並且需要在執行時根據實際的輸入來確定元素型別。因此在執行時消耗記憶體較多。

3. 可使用Froeach 關鍵字操作ArrayList。

ArrayList支援String,int,以及十進位制小數型別。


四、HashTable(雜湊表)

HashTable是一種定義關鍵字的資料結構體,使用雜湊表查詢資料非常方便,雜湊表既不是強型別也不固定大小限制。


五、Stack

棧是最典型的資料結構,棧具有優先順序劃分的資料結構,棧為每個內容項定義優先順序,表示每個Item入棧和出棧的優先順序。因此操作棧中的資料,需要先將資料push 到棧的頂部,需要刪除元素必須變成棧頂部,即要遵守後進先出(LIFO)的原則。

棧與雜湊表一樣既不是強型別也不限制元素個數。

Push 操作

  1. //Stack is LIFO: Last in First Out
  2. System.Collections.Stack objStackPush = new System.Collections.Stack();

  3. //By Push method you can insert item at the top of the stack
  4. objStackPush.Push("Mahsa");
  5. objStackPush.Push("Hassankashi");
  6. this.lblPop.Text = "";
  7. this.ListBoxStack.DataSource = objStackPush.ToArray();
  8. this.ListBoxStack.DataBind();
複製程式碼

Pop操作

  1. System.Collections.Stack objStackPop = new System.Collections.Stack();
  2.    
  3. objStackPop.Push("Mahsa");
  4. objStackPop.Push("Hassankashi");

  5. //By Pop method you can remove item from the top of the stack --> Last in First in
  6. this.lblPop.Text = objStackPop.Pop().ToString();

  7. this.ListBoxStack.DataSource = objStackPop.ToArray();
  8. this.ListBoxStack.DataBind();
複製程式碼

六、Queue

Queue同棧一樣也是具有優先順序定義的結構體,遵循的規則是先進先出(FIFO),既不是強型別也不具有固定的大小限制。

入隊操作

  1. //Queue is FIFO: First in First Out
  2. System.Collections.Queue objQueue = new System.Collections.Queue();

  3. //By Enqueue method you can insert item at the END of the Queue
  4. objQueue.Enqueue("Mahsa");
  5. objQueue.Enqueue("Hassankashi");
  6. objQueue.Enqueue("Cosmic");
  7. objQueue.Enqueue("Verse");

  8. this.lblQueue.Text = "";
  9. this.ListBoxQueue.DataSource = objQueue.ToArray();
  10. this.ListBoxQueue.DataBind();
複製程式碼
出隊操作
  1. System.Collections.Queue objQueue = new System.Collections.Queue();

  2. objQueue.Enqueue("Mahsa");
  3. objQueue.Enqueue("Hassankashi");
  4. objQueue.Enqueue("Cosmic");
  5. objQueue.Enqueue("Verse");

  6. //By Dequeue method you can remove item from the BEGINING of the Queue --> First in First out FIFO
  7. this.lblQueue.Text=objQueue.Dequeue().ToString();

  8. this.ListBoxQueue.DataSource = objQueue.ToArray();
  9. this.ListBoxQueue.DataBind();
複製程式碼

入隊操作

  1. System.Collections.Queue objQueue = new System.Collections.Queue();

  2. objQueue.Enqueue("Mahsa");
  3. objQueue.Enqueue("Hassankashi");
  4. objQueue.Enqueue("Cosmic");
  5. objQueue.Enqueue("Verse");

  6. //By Dequeue method you can remove item from the BEGINING of the Queue --> First in First out FIFO
  7. this.lblQueue.Text=objQueue.Dequeue().ToString();

  8. this.ListBoxQueue.DataSource = objQueue.ToArray();
  9. this.ListBoxQueue.DataBind();
複製程式碼

七、List

什麼情況下需要使用List?

1. List長度可不固定

2. 當資料為通用型別,List是強型別,List中元素型別不需要等到執行時來確定,這種特性使得List 執行時效率非常高。

3. 可使用Foreach關鍵字。

因為List不需要設定固定的大小,List靈活度高,且效率高常用於開發過程中。

  1. //Like Array is Strong Type
  2. //Like ArrayList with No Dimension
  3. System.Collections.Generic.List<string> strList = new List<string>();

  4. strList.Add("Mahsa");
  5. strList.Add("Hassankashi");
  6. strList.Add("Cosmic");
  7. strList.Add("Verse");

  8. this.ListBoxListGeneric.DataSource = strList;
  9. this.ListBoxListGeneric.DataBind();
  10.   
  11. System.Text.StringBuilder str = new System.Text.StringBuilder();

  12. foreach (var item in strList)
  13. {
  14.    str.Append(" , " + item);
  15. }
  16. this.lblList.Text = str.ToString();
複製程式碼

八、IList

IList 繼承了List,包含多種方法的List介面。如果你無法判斷程式碼改動的可能性,可以使用IList介面,減少模組之間的依賴性。IList是介面因此無法被例項化,所以必須使用List來初始化。

  1. //Ilist can not be instantiate from Ilist , so it should be instantiate from List
  2. System.Collections.Generic.IList<string> strIList = new List<string>();

  3. strIList.Add("Mahsa");
  4. strIList.Add("Hassankashi");
  5. strIList.Add("Cosmic");
  6. strIList.Add("Verse");
  7.   
  8. this.ListBoxListGeneric.DataSource = strIList;
  9. this.ListBoxListGeneric.DataBind();
  10.   
  11. System.Text.StringBuilder str = new System.Text.StringBuilder();

  12. foreach (var item in strIList)
  13. {
  14.     str.Append(" , " + item);
  15. }
  16. this.lblList.Text = str.ToString();
複製程式碼

我們一起了解一下具體的類和介面之間的區別。

1. 具體類可繼承其他類,並實現一個或多個介面。

2. 在內部類中可以定義變數並賦值,介面中不允許此操作。

3. 具體類可包含建構函式,而介面中不能定義建構函式

4. 抽象類中可包含訪問修飾符如public,private等,介面中不能包含。


  1. //IEnumerable can not be instantiate from Enumerable , so it should be instantiate from List
  2.      System.Collections.Generic.IEnumerable<Employee> empIEnumerable = new List<Employee>         {   
  3.          new Employee { ID = 1001, Name="Mahsa"},
  4.          new Employee { ID = 1002, Name = "Hassankashi" },
  5.          new Employee { ID = 1003, Name = "CosmicVerse" },
  6.          new Employee { ID = 1004, Name = "Technical" }
  7.      };

  8.       this.GridViewIEnumerable.DataSource = empIEnumerable;
  9.       this.GridViewIEnumerable.DataBind();

  10.       System.Text.StringBuilder str = new System.Text.StringBuilder();

  11.       foreach (Employee item in empIEnumerable)
  12.       {
  13.     str.Append(" , " + item.ID +"-"+item.Name);
  14.       }
  15.      this.lblIEnumerable.Text = str.ToString();
複製程式碼

九、IEnumerable

IEnumerable常用於遍歷集合元素,但是無法修改(刪除或新增)資料,使用IEnumberable 會從伺服器端將所有資料拷貝到客戶端,並進行一定的過濾,如果伺服器端有大量資料會造成記憶體負載超重。

  1. //IEnumerable can not be instantiate from Enumerable , so it should be instantiate from List
  2.      System.Collections.Generic.IEnumerable<Employee> empIEnumerable = new List<Employee>         {   
  3.          new Employee { ID = 1001, Name="Mahsa"},
  4.          new Employee { ID = 1002, Name = "Hassankashi" },
  5.          new Employee { ID = 1003, Name = "CosmicVerse" },
  6.          new Employee { ID = 1004, Name = "Technical" }
  7.      };


  8.       this.GridViewIEnumerable.DataSource = empIEnumerable;
  9.       this.GridViewIEnumerable.DataBind();

  10.       System.Text.StringBuilder str = new System.Text.StringBuilder();

  11.       foreach (Employee item in empIEnumerable)
  12.       {
  13.     str.Append(" , " + item.ID +"-"+item.Name);
  14.       }
  15.      this.lblIEnumerable.Text = str.ToString();
複製程式碼

十、IQueryable
IQueryable與IEnumberable不同的是,當從伺服器端載入過量的資料,IQueryable會自動減少應用負載。IQueryable可保證大資料量時應用程式的高效能。IQueryable會先過濾資料,然後傳送給客戶端。
  1. DataAccessEntities ctx = new DataAccessEntities();
  2.        var ctx = new DataAccessEntities();
複製程式碼




十一、SQL Profiler:

如何追蹤查詢語句生成TSQL,生成需要的資料結構體:

Step 1:
  1. Start -> MS SQL Server 2008 -> Performance Tools -> SQL Server Profiler
複製程式碼

Step 2:
  1. SQL Server Profiler -> File -> New Trace
複製程式碼

Step 3:

輸入連線資料庫的使用者名稱和密碼

Step 4:
  1. General (Tab) -> Use the Template: Standard
複製程式碼

Step 5:
  1. Event Selection (Tab) -> Event : TSQL -> Select : SQL-BatchCompleted | Select Show all Columns

  2. Press Column Filter -> Database Name: Like: "DataAccess"
複製程式碼

執行

Step 6:

檢視結果

Step 7:
生成 IEnumerable資料 :
  1. SELECT 
  2. [Extent1].[ID] AS [ID], 
  3. [Extent1].[Name] AS [Name], 
  4. [Extent1].[Age] AS [Age]
  5. FROM [dbo].[Employee] AS [Extent1]
複製程式碼

生成 IQueryable :
  1. SELECT 
  2. [Extent1].[ID] AS [ID], 
  3. [Extent1].[Name] AS [Name], 
  4. [Extent1].[Age] AS [Age]
  5. FROM [dbo].[Employee] AS [Extent1]
  6. WHERE 1 = [Extent1].[ID]
複製程式碼

ICollection 繼承了IEnumberable,但是IEnumberable是基於索引的,ICollection不基於索引。

十二、Stack Generic

入棧:

  1. //Stack is LIFO: Last in First Out
  2. //Here is for Push Stack in Generic
  3. //System.Collections.Stack objStackPush = new System.Collections.Stack();
  4. //Stack<T> can be instantiated from Stack<T>

  5. System.Collections.Generic.Stack<int> objStackPush = new System.Collections.Generic.Stack<int>();
  6.   
  7. objStackPush.Push(1);
  8. objStackPush.Push(2);
  9.   
  10. this.lblPopGeneric.Text = "";
  11. this.ListBoxStackGeneric.DataSource = objStackPush.ToArray();
  12. this.ListBoxStackGeneric.DataBind();
複製程式碼
Queue Generic

入隊:

  1. //Stack is LIFO: Last in First Out
  2. //Here is for Pop Stack in Generic
  3. //System.Collections.Stack objStackPop = new System.Collections.Stack();
  4. //Stack<T> can be instantiated from Stack<T>

  5. System.Collections.Generic.Stack<int> objStackPop = new System.Collections.Generic.Stack<int>();

  6. objStackPop.Push(1);
  7. objStackPop.Push(2);

  8. this.lblPop.Text = objStackPop.Pop().ToString();
  9. this.ListBoxStack.DataSource = objStackPop.ToArray();
  10. this.ListBoxStack.DataBind();
複製程式碼

出隊:

  1. //Queue is FIFO: First in First Out
  2. //Here is for Enqueue Queue in Generic
  3. //System.Collections.Queue objQueue = new System.Collections.Queue();
  4. //Queue<T> can be instantiated from Queue<T>
  5. System.Collections.Generic.Queue<int> objQueue = new System.Collections.Generic.Queue<int>();
  6. objQueue.Enqueue(1);
  7. objQueue.Enqueue(2);

  8. this.lblQueue.Text = "";

  9. this.ListBoxQueue.DataSource = objQueue.ToArray();
  10. this.ListBoxQueue.DataBind();
複製程式碼
十三、Dictionary 及 IDictionary:
Dictionary 可通用,而雜湊表不是通用的。Dictionary定義 <TKey,Tvalue>。IDictionary是Dictionary的介面,如果在後期開發中需要大量修改,建議使用IDictionary。
  1. System.Collections.Generic.Dictionary<int, string=""> objDictionary = new Dictionary<int, string="">();

  2. objDictionary.Add(1001, "Mahsa");
  3. objDictionary.Add(1002, "Hassankashi");
  4. objDictionary.Add(1003, "Cosmicverse");

  5. string str = objDictionary[1002];

  6. this.ListBoxDictionary.DataSource = objDictionary;
  7. this.ListBoxDictionary.DataBind();</int,>
複製程式碼
來源:http://blog.csdn.net/long316/article/details/52595248

相關文章