一.引言
无论是哪种语言,数据结构都是最基本也是必须要熟悉的,每种语言的数据结构都有属于自己的特性,下面整理一下C#中的常用数据结构
二.ArrayList
- ArrayList的本质
ArrayList是一个C#为我们封装好的类,它的本质是一个object类型的数组,ArrayList类帮助我们实现了很多方法,比如数组的增删查改 - 声明以及增删改查
遍历就不展示了,比较简单,值得一提的是,因为ArrayList内部维护的是一个object类型的数组,所以存取基本类型的变量,存在拆箱和装箱,所以ArrayList尽量少用//需要引用命名空间using System.Collections; ArrayList array = new ArrayList(); #endregion #region 知识点三 增删查改 #region 增 array.Add(1); array.Add("123"); array.Add(true); array.Add(new object()); array.Add(new Test()); array.Add(1); array.Add(true); ArrayList array2 = new ArrayList(); array2.Add(123); //范围增加(批量增加 把另一个list容器里面的内容加到后面) array.AddRange(array2); array.Insert(1, "12345676"); Console.WriteLine(array[1]); #endregion #region 删 //移除指定元素 从头找 找到删 array.Remove(1); //移除指定位置的元素 array.RemoveAt(2); //清空 //array.Clear(); #endregion #region 查 //得到指定位置的元素 Console.WriteLine(array[0]); //查看元素是否存在 if( array.Contains("1234") ) { Console.WriteLine("存在123"); } //正向查找元素位置 //找到的返回值 是位置 找不到 返回值 是-1 int index = array.IndexOf(true); Console.WriteLine(index); Console.WriteLine(array.IndexOf(false)); //反向查找元素位置 //返回时从头开始的索引数 index = array.LastIndexOf(true); Console.WriteLine(index); #endregion #region 改 Console.WriteLine(array[0]); array[0] = "999"; Console.WriteLine(array[0]); #endregion #endregion
与之相类似的还有支持泛型的List类,用法差不多,只是说可以支持元素泛型化
三.栈Stack
- Stack的本质
和ArrayList类似,都是维护了一个Object数组,基本规则是后进先出 - 声明以及使用
遍历的话,可以转数组,或者foreach遍历,但都是从栈顶到栈底的遍历顺序,使用方式和Java中使用foreach遍历数组的方式一样#region 知识点二 申明 //需要引用命名空间 System.Collections Stack stack = new Stack(); #endregion #region 知识点三 增取查改 #region 增 //压栈 stack.Push(1); stack.Push("123"); stack.Push(true); stack.Push(1.2f); stack.Push(new Test()); #endregion #region 取 //栈中不存在删除的概念 //只有取的概念 //弹栈 object v = stack.Pop(); Console.WriteLine(v); v = stack.Pop(); Console.WriteLine(v); #endregion #region 查 //1.栈无法查看指定位置的 元素 // 只能查看栈顶的内容 v = stack.Peek(); Console.WriteLine(v); v = stack.Peek(); Console.WriteLine(v); //2.查看元素是否存在于栈中 if( stack.Contains("123") ) { Console.WriteLine("存在123"); } #endregion #region 改 //栈无法改变其中的元素 只能压(存)和弹(取) //实在要改 只有清空 stack.Clear(); Console.WriteLine(stack.Count); stack.Push("1"); stack.Push(2); stack.Push("哈哈哈"); #endregion #endregion
四.队列Queue
- Queue的本质
和上面同理,维护object数组,系统封装一些列API,规则是先进先出 - 声明及使用
遍历也是同理,这里不做赘述#region 知识点二 申明 //需要引用命名空间 System.Collections Queue queue = new Queue(); #endregion #region 知识点三 增取查改 #region 增 queue.Enqueue(1); queue.Enqueue("123"); queue.Enqueue(1.4f); queue.Enqueue(new Test()); #endregion #region 取 //队列中不存在删除的概念 //只有取的概念 取出先加入的对象 object v = queue.Dequeue(); Console.WriteLine(v); v = queue.Dequeue(); Console.WriteLine(v); #endregion #region 查 //1.查看队列头部元素但不会移除 v = queue.Peek(); Console.WriteLine(v); v = queue.Peek(); Console.WriteLine(v); //2.查看元素是否存在于队列中 if( queue.Contains(1.4f) ) { Console.WriteLine("队列中存在1.4f"); } #endregion #region 改 //队列无法改变其中的元素 只能进出队列 //实在要改 只有清 Console.WriteLine(queue.Count); queue.Clear(); queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); #endregion #endregion
五.HashTable
称之为散列表,是一种键值对的形式存储
- 增删改查
#region 知识点二 申明 //需要引用命名空间 System.Collections Hashtable hashtable = new Hashtable(); #endregion #region 知识点三 增删查改 #region 增 hashtable.Add(1, "123"); hashtable.Add("123", 2); hashtable.Add(true, false); hashtable.Add(false, false); //注意:不能出现相同键 #endregion #region 删 //1.只能通过键去删除 hashtable.Remove(1); //2.删除不存在的键 没反应 hashtable.Remove(2); //3.或者直接清空 hashtable.Clear(); hashtable.Add(1, "123"); hashtable.Add(2, "1234"); hashtable.Add(3, "123"); hashtable.Add("123123", 12); #endregion #region 查 //1.通过键查看值 // 找不到会返回空 Console.WriteLine(hashtable[1]); Console.WriteLine(hashtable[4]);//null Console.WriteLine(hashtable["123123"]); //2.查看是否存在 //根据键检测 if( hashtable.Contains(2) ) { Console.WriteLine("存在键为2的键值对"); } if( hashtable.ContainsKey(2) ) { Console.WriteLine("存在键为2的键值对"); } //根据值检测 if( hashtable.ContainsValue(12) ) { Console.WriteLine("存在值为12的键值对"); } #endregion #region 改 //只能改 键对应的值内容 无法修改键 Console.WriteLine(hashtable[1]); hashtable[1] = 100.5f; Console.WriteLine(hashtable[1]); #endregion #endregion - 遍历
这里顺便提一下与之类似的结构Dictionary,只是说能支持key和value泛型化,遍历会有一点不同,下面是Dictionary的遍历方式//得到键值对 对数 Console.WriteLine(hashtable.Count); //1.遍历所有键 foreach (object item in hashtable.Keys) { Console.WriteLine("键:"+item); Console.WriteLine("值:"+hashtable[item]); } //2.遍历所有值 foreach (object item in hashtable.Values) { Console.WriteLine("值:" + item); } //3.键值对一起遍历 foreach (DictionaryEntry item in hashtable) { Console.WriteLine("键:" + item.Key + "值:" + item.Value); } //4.迭代器遍历法 IDictionaryEnumerator myEnumerator = hashtable.GetEnumerator(); bool flag = myEnumerator.MoveNext(); while (flag) { Console.WriteLine("键:" + myEnumerator.Key + "值:" + myEnumerator.Value); flag = myEnumerator.MoveNext(); }//1.遍历所有键 foreach (int item in dictionary.Keys) { Console.WriteLine(item); Console.WriteLine(dictionary[item]); } //2.遍历所有值 Console.WriteLine("**************"); foreach (string item in dictionary.Values) { Console.WriteLine(item); } //3.键值对一起遍历 Console.WriteLine("**************"); foreach (KeyValuePair<int,string> item in dictionary) { Console.WriteLine("键:" + item.Key + "值:" + item.Value); }
六.链式存储-LinkedList
- 本质
本质是一个可变类型的泛型双向链表 - 声明以及使用
#region 知识点二 申明 //需要引用命名空间 //using System.Collections.Generic LinkedList<int> linkedList = new LinkedList<int>(); LinkedList<string> linkedList2 = new LinkedList<string>(); //链表对象 需要掌握两个类 //一个是链表本身 一个是链表节点类LinkedListNode #endregion #region 知识点三 增删查改 #region 增 //1.在链表尾部添加元素 linkedList.AddLast(10); //2.在链表头部添加元素 linkedList.AddFirst(20); //3.在某一个节点之后添加一个节点 // 要指定节点 先得得到一个节点 LinkedListNode<int> n = linkedList.Find(20); linkedList.AddAfter(n, 15); //4.在某一个节点之前添加一个节点 // 要指定节点 先得得到一个节点 linkedList.AddBefore(n, 11); #endregion #region 删 //1.移除头节点 linkedList.RemoveFirst(); //2.移除尾节点 linkedList.RemoveLast(); //3.移除指定节点 // 无法通过位置直接移除 linkedList.Remove(20); //4.清空 linkedList.Clear(); linkedList.AddLast(1); linkedList.AddLast(2); linkedList.AddLast(3); linkedList.AddLast(4); #endregion #region 查 //1.头节点 LinkedListNode<int> first = linkedList.First; //2.尾节点 LinkedListNode<int> last = linkedList.Last; //3.找到指定值的节点 // 无法直接通过下标获取中间元素 // 只有遍历查找指定位置元素 LinkedListNode<int> node = linkedList.Find(3); Console.WriteLine(node.Value); node = linkedList.Find(5); //4.判断是否存在 if( linkedList.Contains(1) ) { Console.WriteLine("链表中存在1"); } #endregion #region 改 //要先得再改 得到节点 再改变其中的值 Console.WriteLine(linkedList.First.Value); linkedList.First.Value = 10; Console.WriteLine(linkedList.First.Value); #endregion #endregion - 遍历
//1.foreach遍历 foreach (int item in linkedList) { Console.WriteLine(item); } //2.通过节点遍历 // 从头到尾 Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&"); LinkedListNode<int> nowNode = linkedList.First; while (nowNode != null) { Console.WriteLine(nowNode.Value); nowNode = nowNode.Next; } // 从尾到头 Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&"); nowNode = linkedList.Last; while (nowNode != null) { Console.WriteLine(nowNode.Value); nowNode = nowNode.Previous; }