在世界上有很多东西,储存的数据并不需要在意中间部分的数据。
例如贪吃蛇,中间的身子部分不参与移动。每次移动只有尾巴消失,头增加一格。
像这样的东西,方法和属性就比列表少得多。因为也没什么能操作的。
Queue入列queue = new Queue ();
queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3);
使用Enqueue方法可以把一个值添加到末尾处。
出列int i1 = queue.Dequeue(); bool b1 = queue.TryDequeue(out int i2);
Dequeue方法会移除最开始的值。这个值同时会作为返回值被返回。
如果队列里没有元素,那么Dequeue方法会报错。
如果不想检查元素数量,可以使用TryDequeue方法,他使用out参数输出值。
方法本身返回bool值,指示是否成功输出。
有时候需要先确定开头的值已经达到想要的状态,才拿出来。
这样也需要获得值,但不移除。可以使用Peek或TryPeek方法。
int i3 = queue.Peek(); bool b2 = queue.TryPeek(out int i4);
如果没有元素,Peek方法也会报错。
同样可以使用TryPeek方法代替,out参数输出值,方法本身返回是否成功获得值。
Count属性指示当前剩余元素。
Contains方法确认指定元素是否已经存在。
EnsureCapacity扩大这个队列背后数组的容量,直到达到指定值。
和队列相反,拿出来的是最近放进去的东西,最早放进去的东西拿的最晚。
像这样的路径点,如果新路径和上一个路径一样,那么移除一个路径点。
总体使用方法和队列差不多,只是放入和取出两个方法的名字变了。
Stack双链表stack = new Stack (); stack.Push(1); stack.Push(2); stack.Push(3);//Push方法入栈 var i1 = stack.Pop(); var i2 = stack.Pop();//Pop方法出栈(移除最新放入的元素,并作为返回值返回) var b1 = stack.TryPop(out int i3);//尝试出栈 var i4 = stack.Peek();//瞄一眼 var b2 = stack.TryPeek(out int i5);//尝试瞄一眼
链表的每个节点都是独立的。
数组如果想从中间插入一个数据,那么从这个位置到末尾的数据全部都要挪动。
删除数据也是,后面的数据全部都要往前挪一位。
链表的插入和删除就不需要这么复杂,只需要对自己和自己链接的节点操作就行了。
但是缺点也很大,节点记录了前一个节点和后一个节点的位置,多出了更多的空间占用。
并且如果想找到中间某个节点的位置,只能按着节点的指示顺着查找,每次查找都要进行一次遍历。
所以其他的数据集合背后都使用数组作为容器。数组作为最基本的结构仍然具有很多优势。
LinkedList添加元素linkedList=new LinkedList ();
linkedList.AddFirst(0); linkedList.AddLast(1);
链表储存的是节点类,但收尾处的数据添加可以直接使用数据添加,他会自动帮你打包成节点类。
获取节点双链表的First和Last属性可以获得首尾的节点。
或者,Find方法和FindLast方法,可以搜索包含指定值的节点。
LinkedListNodeL1 = linkedList.First; LinkedListNode L2 = linkedList.Last; LinkedListNode L3 = linkedList.Find(0); LinkedListNode L4 = linkedList.Find(1);
在找不到节点时,会返回null而不会报错(特指First和Last属性)。
节点属性每个节点都包含了本身的值,上一个节点,下一个节点,所属的双链表。
c#的这个双链表用于作为链式储存的数据集,不能提供一般链表的拆分、周期等功能。
int i = L1.Value;//获得值 LinkedListNodeL2 = L1.Previous;//获得上一个节点 LinkedListNode L3 = L1.Next;//获得下一个节点 LinkedList link = L1.List;//获得所属链表



