当前位置: 首页 > 编程语言 > C#

C#-LinkedList-如何删除指定节点之后的所有节点?分享

时间:2023-04-10 23:23:28 C#

C#-LinkedList-如何删除指定节点之后的所有节点?我正在使用通用LinkedList实现撤消/重做缓冲区。在这个状态下:[best]state4(undo)state3(undo)state2<-currentstatestate1[bottom]当我做Push的时候,我想删除当前状态之后的所有状态,然后推送新的状态。我目前的绕过是while(currentState!=list.last),list.removeLast();但它很糟糕LinkedList只支持Remove、RemoveFirst和removeLast...我想要像RemoveAllNodesAfter(LinkedListNode...)这样的东西?如何在不遍历所有节点的情况下很好地编码?也许有扩展?...我在标准的LinkedList中看不到任何可以让你这样做的东西。如果需要,您可以查看PowerCollections和C5集合-或者只是滚动您自己的LinkedList类型。它是实现起来比较简单的集合之一,尤其是当您可以“及时”方式添加功能时。如果我要自己实现它,我会选择不同的方式来实现它。我会选择创建一个.SplitAfter(node)方法,而不是.RemoveAllNodesAfter(node)方法,该方法返回一个新的链表,该链表从节点之后的下一个节点开始。这将是一个比仅仅能够切断尾巴更方便的工具。如果你想要你的RemoveAllNodesAfter方法,它只需要在内部调用SplitAfter方法并丢弃结果。简单的实现:publicLinkedListSplitAfter(Nodenode){NodenextNode=node.Next;//断链node.Next=null;nextNode.Previous=null;返回新的链表(下一个节点);}publicvoidRemoveAllNodesAfter(Nodenode){SplitAfter(node);}链表(尤其是单链表)是最基本的基本集合结构之一。我相信您可以轻松实现它(并添加您需要的行为)。事实上,您并不真的需要一个集合类来管理列表。您可以在没有集合类的情况下管理节点。公共类SingleLinkedListNode{私有只读T值;接下来是私有SingleLinkedListNode;publicSingleLinkedListNode(Tvalue,SingleLinkedListNodenext){this.value=value;}publicSingleLinkedListNode(Tvalue,SingleLinkedListNodenext):this(value){this.next=next;}publicSingleLinkedListNodeNext{get{returnnext;}设置{下一个=值;}}publicTValue{get{返回值;但是,如果您对可能的实现感兴趣,这里有一个简单的SingleLinkedList实现。公共类SingleLinkedList{私有SingleLinkedListNode头;私有SingleLinkedListNode尾部;publicSingleLinkedListNodeHead{get{返回头;}设置{头=值;}}publicIEnumerable>Nodes{get{SingleLinkedListNodecurrent=head;while(current!=null){yieldreturncurrent;当前=当前.下一个;}}}publicSingleLinkedListNodeAddToTail(Tvalue){if(head==null)returncreateNewHead(value);如果(尾==null)尾=findTail();SingleLinkedListNodenewNode=newSingleLinkedListNode(value,null);tail.Next=newNode;返回新节点;}publicSingleLinkedListNodeInsertAtHead(Tvalue){if(head==null)returncreateNewHead(value);SingleLinkedListNodeoldHead=Head;SingleLinkedListNodenewNode=newSingleLinkedListNode(value,oldHead);头=新节点;返回新节点;}publicSingleLinkedListNodeInsertBefore(Tvalue,SingleLinkedListNodetoInsertBefore){if(head==null)thrownewInvalidOperationException(“你不能插入一个空列表。”);如果(头==toInsertBefore)返回InsertAtHead(值);SingleLinkedListNodenodeBefore=findNodeBefore(toInsertBefore);SingleLinkedListNodetoInsert=newSingleLinkedListNode(value,toInsertBefore);nodeBefore.Next=toInsert;返回插入;}publicSingleLinkedListNodeAppendAfter(Tvalue,SingleLinkedListNodetoAppendAfter){SingleLinkedListNodenewNode=newSingleLinkedListNode(value,toAppendAfter.Next);toAppendAfter.Next=newNode;返回新节点;}publicvoidTruncateBefore(SingleLinkedListNodetoTruncateBefore){if(head==toTruncateBefore){head=null;尾=空;返回;}SingleLinkedListNodenodeBefore=findNodeBefore(toTruncateBefore);if(nodeBefore!=null)nodeBefore.Next=null;}publicvoidTruncateAfter(SingleLinkedListNodetoTruncateAfter){toTruncateAfter.Next=null;}privateSingleLinkedListNodecreateNewHead(Tvalue){SingleLinkedListNodenewNode=newSingleLinkedListNode(值,空);头=新节点;尾=新节点;返回新节点;}privateSingleLinkedListNodefindTail(){if(head==null)returnnull;SingleLinkedListNodecurrent=head;while(current.Next!=null){current=current.Next;}返回电流;}privateSingleLinkedListNodefindNodeBefore(SingleLinkedListNodenodeToFindNodeBefore){SingleLinkedListNodecurrent=head;while(current!=null){if(current.Next!=null&¤t.Next==nodeToFindNodeBefore)返回当前;当前=当前.下一个;}返回空值;}}现在你可以这样做:publicstaticvoidMain(string[]args){SingleLinkedListlist=newSingleLinkedList();list.InsertAtHead("state4");list.AddToTail("state3");list.AddToTail("state2");list.AddToTail("state1");SingleLinkedListNode当前=null;foreach(list.Nodes中的SingleLinkedListNode节点){如果(node.Value!=“state2”)继续;当前=节点;休息;}if(current!=null)list.TruncateAfter(current);}事情取决于在你的情况下,没有比这更好的了:publicstaticvoidMain(string[]args){first.Next=newSingleLinkedListNode("state3");SingleLinkedListNodecurrent=first.Next;current.Next=newSingleLinkedListNode("state2");当前=当前.下一个;current.Next=newSingleLinkedListNode("state1");当前=第一;while(current!=null){if(current.Value!="state2")继续;当前.下一个=空;当前=当前.下一个;休息;这完全消除了对集合类的需要或者,您可以这样做:while(currentNode.Next!=null)list.Remove(currentNode.Next);实际上,链表是一种相当简单的数据结构,尤其是在托管代码中实现的(阅读:没有内存管理的麻烦)。这是我支持的一个支持足够的函数(读取:YAGNI)来支持你的营销/重做操作:publicclassLinkedListNode{publicLinkedListParent{get;放;}公共T值{得到;放;}publicLinkedListNodeNext{得到;放;}publicLinkedListNodePrevious{get;放;}}publicclassLinkedList:IEnumerable{publicLinkedListNodeLast{get;私有集;}publicLinkedListNodeAddLast(Tvalue){Last=(Last==null)?newLinkedListNode{Previous=null}:Last.Next=newLinkedListNode{Previous=Last};Last.Parent=这个;Last.Value=值;最后一个。下一个=空;最后返回;}publicvoidSevereAt(LinkedListNodenode){if(node.Parent!=this)thrownewArgumentException("Can'tseverenodethatisn'tfromthesameparentlist.");node.Next.Previous=null;节点.Next=null;最后=节点;}IEnumeratorIEnumerable.GetEnumerator(){返回((IEnumerable)this).GetEnumerator();}publicIEnumeratorGetEnumerator(){varwalk=Last;while(walk!=null){yieldreturnwalk.Value;walk=walk.Previous;然后你可以在代码中使用SevereAt方法来“切割”链表,简单明了首先想到的是设置Node.Next.Previous=null(如果是双向链表),然后Node.Next=null。不幸的是,因为LinkedListNode.Next和LinkedListNode.Previous在LinkedList的.NET实现中是只读属性,我认为您可能必须实现自己的结构才能使其工作。但正如其他人所说,这应该很容易。如果您只是在谷歌上搜索C#的链接列表,那么您可以使用大量资源作为起点。if(this.ptr!=null&&this.ObjectName!=null){LinkedListNodeit=ObjectName.Last;for(;it!=this.ptr;it=it.Previous){this.m_ObjectName.Remove(it);}}this.ptr是LinkedListNode类型,仅供参考this.ptr是指向你当前所在节点的指针,我假设你想删除它右边的所有内容。不要复制你的结构,这是最糟糕的主意。它是一个整体内存猪,结构可能非常大。除非绝对必要,否则复制对象不是好的编程习惯。尝试进行就地操作。我做了两个扩展方法“删除特定节点之前的所有节点”和“删除特定节点之后的所有节点”。然而,这些扩展方法是LinkedListNode的扩展,而不是LinkedList本身,只是为了方便:节点.Previous);}publicstaticvoidRemoveAllAfter(thisLinkedListNodenode){while(node.Next!=null)node.List.Remove(node.Previous);}}使用示例:voidMain(){//创建链表并用一些值填充它LinkedListlist=newLinkedList();for(inti=0;i<10;i++)list.AddLast(i);//从列表中选择一些节点(这里是值为3的节点)LinkedListNodenode=list.First.Next.Next.Next;//现在是技巧node.RemoveAllBefore();//或者node.RemoveAllAfter();嗯,这不是最有效的方法,如果你发现如果你自己在大型列表上或经常调用这个方法,那么这里描述的其他方法可能更合适(比如编写你自己的允许拆分的链表类,如其他答案)但如果它只是偶尔的“在这里和那里删除节点”比那更简单并且非常直观。以上就是C#学习教程:C#-LinkedList-如何删除指定节点之后的所有节点?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: