最全的數據結構解析與歸納
本文對常用的數據結構: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 操作
//Stack is LIFO: Last in First Out
System.Collections.Stack objStackPush = new System.Collections.Stack();
//By Push method you can insert item at the top of the stack
objStackPush.Push("Mahsa");
objStackPush.Push("Hassankashi");
this.lblPop.Text = "";
this.ListBoxStack.DataSource = objStackPush.ToArray();
this.ListBoxStack.DataBind();
複製代碼
Pop操作
System.Collections.Stack objStackPop = new System.Collections.Stack();
objStackPop.Push("Mahsa");
objStackPop.Push("Hassankashi");
//By Pop method you can remove item from the top of the stack --> Last in First in
this.lblPop.Text = objStackPop.Pop().ToString();
this.ListBoxStack.DataSource = objStackPop.ToArray();
this.ListBoxStack.DataBind();
複製代碼
六、Queue
Queue同棧一樣也是具有優先級定義的結構體,遵循的規則是先進先出(FIFO),既不是強類型也不具有固定的大小限制。
入隊操作
//Queue is FIFO: First in First Out
System.Collections.Queue objQueue = new System.Collections.Queue();
//By Enqueue method you can insert item at the END of the Queue
objQueue.Enqueue("Mahsa");
objQueue.Enqueue("Hassankashi");
objQueue.Enqueue("Cosmic");
objQueue.Enqueue("Verse");
this.lblQueue.Text = "";
this.ListBoxQueue.DataSource = objQueue.ToArray();
this.ListBoxQueue.DataBind();
複製代碼
出隊操作
System.Collections.Queue objQueue = new System.Collections.Queue();
objQueue.Enqueue("Mahsa");
objQueue.Enqueue("Hassankashi");
objQueue.Enqueue("Cosmic");
objQueue.Enqueue("Verse");
//By Dequeue method you can remove item from the BEGINING of the Queue --> First in First out FIFO
this.lblQueue.Text=objQueue.Dequeue().ToString();
this.ListBoxQueue.DataSource = objQueue.ToArray();
this.ListBoxQueue.DataBind();
複製代碼
入隊操作
System.Collections.Queue objQueue = new System.Collections.Queue();
objQueue.Enqueue("Mahsa");
objQueue.Enqueue("Hassankashi");
objQueue.Enqueue("Cosmic");
objQueue.Enqueue("Verse");
//By Dequeue method you can remove item from the BEGINING of the Queue --> First in First out FIFO
this.lblQueue.Text=objQueue.Dequeue().ToString();
this.ListBoxQueue.DataSource = objQueue.ToArray();
this.ListBoxQueue.DataBind();
複製代碼
七、List
什麼情況下需要使用List?
1. List長度可不固定
2. 當數據爲通用類型,List是強類型,List中元素類型不需要等到運行時來確定,這種特性使得List 運行時效率非常高。
3. 可使用Foreach關鍵字。
因爲List不需要設定固定的大小,List靈活度高,且效率高常用於開發過程中。
//Like Array is Strong Type
//Like ArrayList with No Dimension
System.Collections.Generic.List<string> strList = new List<string>();
strList.Add("Mahsa");
strList.Add("Hassankashi");
strList.Add("Cosmic");
strList.Add("Verse");
this.ListBoxListGeneric.DataSource = strList;
this.ListBoxListGeneric.DataBind();
System.Text.StringBuilder str = new System.Text.StringBuilder();
foreach (var item in strList)
{
str.Append(" , " + item);
}
this.lblList.Text = str.ToString();
複製代碼
八、IList
IList 繼承了List,包含多種方法的List接口。如果你無法判斷代碼改動的可能性,可以使用IList接口,減少模塊之間的依賴性。IList是接口因此無法被實例化,所以必須使用List來初始化。
//Ilist can not be instantiate from Ilist , so it should be instantiate from List
System.Collections.Generic.IList<string> strIList = new List<string>();
strIList.Add("Mahsa");
strIList.Add("Hassankashi");
strIList.Add("Cosmic");
strIList.Add("Verse");
this.ListBoxListGeneric.DataSource = strIList;
this.ListBoxListGeneric.DataBind();
System.Text.StringBuilder str = new System.Text.StringBuilder();
foreach (var item in strIList)
{
str.Append(" , " + item);
}
this.lblList.Text = str.ToString();
複製代碼
我們一起了解一下具體的類和接口之間的區別。
1. 具體類可繼承其他類,並實現一個或多個接口。
2. 在內部類中可以定義變量並賦值,接口中不允許此操作。
3. 具體類可包含構造函數,而接口中不能定義構造函數
4. 抽象類中可包含訪問修飾符如public,private等,接口中不能包含。
//IEnumerable can not be instantiate from Enumerable , so it should be instantiate from List
System.Collections.Generic.IEnumerable<Employee> empIEnumerable = new List<Employee> {
new Employee { ID = 1001, Name="Mahsa"},
new Employee { ID = 1002, Name = "Hassankashi" },
new Employee { ID = 1003, Name = "CosmicVerse" },
new Employee { ID = 1004, Name = "Technical" }
};
this.GridViewIEnumerable.DataSource = empIEnumerable;
this.GridViewIEnumerable.DataBind();
System.Text.StringBuilder str = new System.Text.StringBuilder();
foreach (Employee item in empIEnumerable)
{
str.Append(" , " + item.ID +"-"+item.Name);
}
this.lblIEnumerable.Text = str.ToString();
複製代碼
九、IEnumerable
IEnumerable常用於遍歷集合元素,但是無法修改(刪除或添加)數據,使用IEnumberable 會從服務器端將所有數據拷貝到客戶端,並進行一定的過濾,如果服務器端有大量數據會造成內存負載超重。
//IEnumerable can not be instantiate from Enumerable , so it should be instantiate from List
System.Collections.Generic.IEnumerable<Employee> empIEnumerable = new List<Employee> {
new Employee { ID = 1001, Name="Mahsa"},
new Employee { ID = 1002, Name = "Hassankashi" },
new Employee { ID = 1003, Name = "CosmicVerse" },
new Employee { ID = 1004, Name = "Technical" }
};
this.GridViewIEnumerable.DataSource = empIEnumerable;
this.GridViewIEnumerable.DataBind();
System.Text.StringBuilder str = new System.Text.StringBuilder();
foreach (Employee item in empIEnumerable)
{
str.Append(" , " + item.ID +"-"+item.Name);
}
this.lblIEnumerable.Text = str.ToString();
複製代碼
十、IQueryable
IQueryable與IEnumberable不同的是,當從服務器端加載過量的數據,IQueryable會自動減少應用負載。IQueryable可保證大數據量時應用程序的高性能。IQueryable會先過濾數據,然後發送給客戶端。
DataAccessEntities ctx = new DataAccessEntities();
var ctx = new DataAccessEntities();
複製代碼
十一、SQL Profiler:
如何追蹤查詢語句生成TSQL,生成需要的數據結構體:
Step 1:
Start -> MS SQL Server 2008 -> Performance Tools -> SQL Server Profiler
複製代碼
Step 2:
SQL Server Profiler -> File -> New Trace
複製代碼
Step 3:
輸入連接數據庫的用戶名和密碼
Step 4:
General (Tab) -> Use the Template: Standard
複製代碼
Step 5:
Event Selection (Tab) -> Event : TSQL -> Select : SQL-BatchCompleted | Select Show all Columns
Press Column Filter -> Database Name: Like: "DataAccess"
複製代碼
運行
Step 6:
查看結果
Step 7:
生成 IEnumerable數據 :
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
[Extent1].[Age] AS [Age]
FROM [dbo].[Employee] AS [Extent1]
複製代碼
生成 IQueryable :
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
[Extent1].[Age] AS [Age]
FROM [dbo].[Employee] AS [Extent1]
WHERE 1 = [Extent1].[ID]
複製代碼
ICollection 繼承了IEnumberable,但是IEnumberable是基於索引的,ICollection不基於索引。
十二、Stack Generic
入棧:
//Stack is LIFO: Last in First Out
//Here is for Push Stack in Generic
//System.Collections.Stack objStackPush = new System.Collections.Stack();
//Stack<T> can be instantiated from Stack<T>
System.Collections.Generic.Stack<int> objStackPush = new System.Collections.Generic.Stack<int>();
objStackPush.Push(1);
objStackPush.Push(2);
this.lblPopGeneric.Text = "";
this.ListBoxStackGeneric.DataSource = objStackPush.ToArray();
this.ListBoxStackGeneric.DataBind();
複製代碼
Queue Generic
入隊:
//Stack is LIFO: Last in First Out
//Here is for Pop Stack in Generic
//System.Collections.Stack objStackPop = new System.Collections.Stack();
//Stack<T> can be instantiated from Stack<T>
System.Collections.Generic.Stack<int> objStackPop = new System.Collections.Generic.Stack<int>();
objStackPop.Push(1);
objStackPop.Push(2);
this.lblPop.Text = objStackPop.Pop().ToString();
this.ListBoxStack.DataSource = objStackPop.ToArray();
this.ListBoxStack.DataBind();
複製代碼
出隊:
//Queue is FIFO: First in First Out
//Here is for Enqueue Queue in Generic
//System.Collections.Queue objQueue = new System.Collections.Queue();
//Queue<T> can be instantiated from Queue<T>
System.Collections.Generic.Queue<int> objQueue = new System.Collections.Generic.Queue<int>();
objQueue.Enqueue(1);
objQueue.Enqueue(2);
this.lblQueue.Text = "";
this.ListBoxQueue.DataSource = objQueue.ToArray();
this.ListBoxQueue.DataBind();
複製代碼
十三、Dictionary 及 IDictionary:
Dictionary 可通用,而哈希表不是通用的。Dictionary定義 <TKey,Tvalue>。IDictionary是Dictionary的接口,如果在後期開發中需要大量修改,建議使用IDictionary。
System.Collections.Generic.Dictionary<int, string=""> objDictionary = new Dictionary<int, string="">();
objDictionary.Add(1001, "Mahsa");
objDictionary.Add(1002, "Hassankashi");
objDictionary.Add(1003, "Cosmicverse");
string str = objDictionary[1002];
this.ListBoxDictionary.DataSource = objDictionary;
this.ListBoxDictionary.DataBind();</int,>