几种常见的数据结构:
线性数据结构,典型的有:数组、栈、队列和线性表
【LinkedList<T>】
链表,在存储元素时,不仅要存储元素的值,还必须存储每个元素的下一个元素和上一个元素的信息。
优点:如果将元素插入到列表的中间位置,使用链表就会很快。在插入一个元素时,只需要修改上一个元素的 Next 引用和下一个元素的 Previous 引用,使它们引用所插入的元素。而在 List<T> 中插入一个元素,需要移动该元素后面的所以元素。
缺点:链表元素只能一个接一个的访问,这需要较长时间来查找位于链表中间或尾部的元素。
First()、Last():访问链表中的第一个和最后一个元素
AddAfter()、AddFirst、AddLast():在指定位置插入元素
Remove(),RemoveFirst()、RemoveLast():删除指定位置的元素
Find()、FindLast():搜索
【Queue】
队列,采用先入先出机制(FLFO, First in First out),不允许直接对队列中非队头元素进行访问和删除,不允许在中间的某个位置插入。
使用:
Count:返回队列中的元素个数
Enqueue():在队列的末端添加元素
Dequeue():在队列的头部读取和删除一个元素。注意,这里读取元素的同时也删除了这个元素。如果队列中不再有任何元素,就抛出异常
Peek():在队列的头读取一个元素,但是不删除它
TrimExcess():重新设置队列的容量,因为调用Dequeue方法读取删除元素后不会重新设置队列的容量
Contains():确定某个元素是否在队列中
CopyTo():把队列复制到一个已有的数组中
ToArray():把队列复制到新数组
Clear():从队列中移除所有对象
声明:
Queue<object> queueData = new Queue<object>();
延伸:
ConcurrentQueue,对线程做了安全处理:https://www.cnblogs.com/zpy1993-09/p/13525421.html
【Array】
数组,它在内存中是连续存储的,所以索引速度很快,而且赋值与修改元素也很简单。
string[] s = new string[3]; //赋值 s[0]="a"; s[1]="b"; s[2]="c"; //修改 s[1]="b1"; //获取元素数量 int length = s.Length;
其他声明方式:定义数组并初始化(也是指明了数组长度)。
string[] array1 = new string[] { "张三", "李四", "王五", "曾静" }; string[] array2 = { "张三", "李四", "王五", "曾静" };
由于数组不能更改长度,所以增加和删除元素只能重新定义数组。
//例如新增元素,我们这里用CopyTo方法来将原来的数组Copy到一个新数组中。 string[] news = new string[4]; s.CopyTo(news, 0); news[3] = "d"; //移除和插入的话,使用for遍历原来的数组赋值给新数组。
//for(int i……
缺点:根据内容查找元素速度慢;只能存储一种类型的数据;声明数组时必须指明数组长度;增加和删除元素效率慢。
改善:ArrayList
【ArrayList】
动态数组,专门用于存储异类对象的集合。可以存多种数据类型,不需要指定它的长度,很方便的进行数据的添加,插入和移除。
ArrayList list = new ArrayList(); //新增数据 list.Add("abc"); list.Add(123); list.Add("张三"); //修改数据 list[1] = 345; //移除数据 list.Remove("张三"); //根据索引移除和插入数据 list.RemoveAt(0); list.Insert(0, "hello world"); //取值(必须进行数据类型转换) string str = (string)list[1]; //获取元素数量 int count = list.Count;
其他方法:
Clear():清除全部元素
Reverse():反转数组的元素
Sort():以从小到大的顺序排列数组的元素
缺点:
因为可存不同类型的数据,所以插入的数据都是当做 object 类型来处理。
那我们在取值的时候,进行错误的类型转换也能通过编译,那么就会报类型不匹配的错误;而且必须的类型转换也存在了装箱和拆箱的操作,增加性能损耗。
改善:泛型List<T>
【泛型 List<T>】
为解决 ArrayList 存在不安全类型与装箱拆箱(额外耗费cpu和内存资源)的缺点,所以在 C# 2.0 之后引入了泛型。T为列表中元素类型,现在以 string 类型作为例子。
//创建一个普通的泛型集合类 List<string> list = new List<string>(); //新增数据 list.Add("张三"); //修改数据 list[0] = "李四"; //移除数据 list.Remove("李四");
List<T> 虽然排除了不安全类型的隐患,但是也限制了存储数据的类型。如果要存储异类对象的集合,可以用 List<object>;
小结:上述经过比较,数组用于保存固定数量的数据,定长,占用内存少,遍历速度快; 集合保存的数据数量,可以在程序的执行过程中,不断发生变化,不定长,占用内存多,遍历速度慢;在功能上,数组能实现的所有功能,集合都能实现;反之,集合能实现的某些功能,数组难以实现。
【HashTable】
哈希表,键值对存储 object 类型,所以支持任何类型的键值对;使用时需要强制转换;key分大小写。
//实例化Hashtable Hashtable hashTable = new Hashtable(); //增加元素 hashTable.Add("姓名", "小芳"); hashTable.Add("性别", "女"); hashTable.Add("年龄", 28); //遍历哈希表 foreach (DictionaryEntry item in hashTable) { Console.WriteLine("哈希键:" + item.Key + ",哈希值:" + item.Value.ToString()); } //遍历键or值 foreach (object value in hashTable.Values) { Console.WriteLine(value); } //删除元素 hashTable.Remove("性别"); //元素个数 int count = hashTable.Count; //取值 string name = (string)hashTable["姓名"]; int age = (int)hashTable["年龄"]; //删除所有元素 hashTable.Clear(); //判断是否包含key bool isKey = hashTable.ContainsKey("姓名"); //判断是否包含value bool isValue = hashTable.ContainsValue("小芳");
【Dictionary】
字典,键值对集合,拥有键和值两种类型,支持 Add 和 Remove,满足键值条件的数据集合。
//创建及初始化 Dictionary<int, string> myDictionary = new Dictionary<int, string>(); //添加元素 myDictionary.Add(1, "C#"); myDictionary.Add(2, "C++"); myDictionary.Add(3, "ASP.NET"); myDictionary.Add(4, "MVC"); //通过Key查找元素 if (myDictionary.ContainsKey(1)) { Console.WriteLine("Key:{0},Value:{1}", "1", myDictionary[1]); } //通过KeyValuePair遍历元素 foreach (KeyValuePair<int, string> kvp in myDictionary) { Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value); } //仅遍历键 Keys 属性 Dictionary<int, string>.KeyCollection keyCol = myDictionary.Keys; foreach (int key in keyCol) { Console.WriteLine("Key = {0}", key); } //仅遍历值 Values 属性 Dictionary<int, string>.ValueCollection valueCol = myDictionary.Values; foreach (string value in valueCol) { Console.WriteLine("Value = {0}", value); } //通过Remove方法移除指定的键值 myDictionary.Remove(1);
其他方法:
Count():获取键/值对的数目
Clear():移除所有的键和值
延伸:
ConcurrentDictionary,对线程做了安全处理。详细
SortedDictionary,字典序排序。
ArrayList、List、Hashtable、Dictionary 的联系与区别:
类别 | ||
Arraylist | 可以添加数据,数据的个数不受限制 | 需要导入命名空间,存的数据不限制类型 |
List | 可以添加数据,数据的个数不受限制 | 不用导入命名空间,确定了存数据的类型 |
Hashtable | 以键值对的形式存值,方法很相似 | 需要导入命名空间,存的数据不限制类型 |
dictionary | 以键值对的形式存值,方法很相似 | 不用导入命名空间,确定了存数据的类型 |
小结:我认为应该始终使用 Dictionary<K, V>,即使要用 Hashtable 了,也可以用 Dictionary<object, object> 来替代。
【DataTable】
https://www.cnblogs.com/qianqian528/p/8456351.html
转载于:
https://www.cnblogs.com/AduBlog/p/13624292.html
https://blog.csdn.net/weixin_44870681/article/details/92068543