问题描述
我在线研究了内置的LinkedList是C#中的双链表。我还研究了LinkedList.Remove(LinkedListNode)方法。但是我仍然找不到我的问题的答案。 以下是代码段:
public string DequeueCat()
{
LinkedListNode<string> temp = animals.First;
while (temp != null && temp.Value.Contains("Cat") == false)
{
temp = temp.Next;
}
if (temp!=null && temp.Value.Contains("Cat"))
{
animals.Remove(temp);
return temp.Value;
}
else
{
Console.WriteLine("No more Cats available");
return null;
}
}
变量animals
的类型为LinkedList<string>
。
当我们用LinkedListNode<string>
实例化一个新的animals.First
时,会发生什么?如LinkedListNode<string> temp = animals.First;
。
是否会进行深度复制,并且原始LinkedList(由animals.First
指向)会在堆上的新位置复制到temp
?
另外,当我们编写animals.Remove(temp)
时,temp
LinkListNode被破坏。并且,将从animals
LinkedList中删除相应的值。
以下是执行animals.Remove(temp)
之前的监视窗口-
然后是执行animals.Remove(temp)
之后的“监视”窗口-
我的问题是,执行temp
后为何animals.Remove(temp)
被销毁?另外,如果temp
是在堆上的另一个位置创建的(与原始LinkedList相比),那么我们如何知道从原始temp
LinkedList中删除animals
从中删除相应的项目
animals
LinkedList?
以下是整个代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AnimalShelter
{
class AnimalsShelter
{
//This class will have the following functions:
//Enqueue,DequeueAny,DeQueueDog,DeQueueCat
//Implement queue using C# inbuilt linked list.
LinkedList<string> animals = new LinkedList<string>();
public void Enqueue(string animal)
{
animals.AddLast(animal);
}
public string DequeueAny()
{
LinkedListNode<string> firstAnimal = animals.First;
if (firstAnimal != null)
{
animals.RemoveFirst();
return firstAnimal.Value;
}
else
{
Console.WriteLine("No more animanls left in queue.");
return null;
}
}
public string DequeueDog()
{
LinkedListNode<string> temp = animals.First;
while(temp!=null && temp.Value.Contains("Dog")==false)
{
temp = temp.Next;
}
if(temp!=null && temp.Value.Contains("Dog"))
{
animals.Remove(temp);
return temp.Value;
}
else
{
Console.WriteLine("No more Dogs available");
return null;
}
}
public string DequeueCat()
{
LinkedListNode<string> temp = animals.First;
while (temp != null && temp.Value.Contains("Cat") == false)
{
temp = temp.Next;
}
if (temp!=null && temp.Value.Contains("Cat"))
{
animals.Remove(temp);
return temp.Value;
}
else
{
Console.WriteLine("No more Cats available");
return null;
}
}
}
class Program
{
static void Main(string[] args)
{
AnimalsShelter shelter = new AnimalsShelter();
shelter.Enqueue("Dog1");
shelter.Enqueue("Dog2");
shelter.Enqueue("Cat1");
shelter.Enqueue("Dog3");
shelter.Enqueue("Cat2");
shelter.Enqueue("Cat3");
Console.WriteLine(shelter.DequeueCat());
Console.WriteLine(shelter.DequeueAny());
Console.WriteLine(shelter.DequeueDog());
Console.WriteLine(shelter.DequeueCat());
Console.WriteLine(shelter.DequeueAny());
Console.WriteLine(shelter.DequeueAny());
}
}
}
任何对此的高度赞赏。谢谢!
解决方法
可变动物的类型为
LinkedList<string>
。到底是什么 当我们实例化一个新的LinkedListNode<string>
时发生animals.First
?如LinkedListNode<string> temp = animals.First;
。 深拷贝是否发生
不。您要做的就是复制参考文献LinkedListNode<string> temp = animals.First;
此外,当我们写
animals.Remove(temp)
时,温度LinkListNode
为 毁了。
不。它并没有被销毁,但是其链接已被删除。仍然是相同的参考。
我的问题是,执行后为什么会破坏temp 动物。要删除(临时)吗?
不。再一次,它没有被摧毁。但是其链接已被删除。
此外,如果已在堆的单独位置上创建了温度
不。尚未在堆上的单独位置创建它,您要做的就是复制引用。
那我们怎么知道从动物身上去除温度 LinkedList将从动物中删除相应的项目 LinkedList
我们知道,因为它是相同的对象/相同的引用。
这里是Remove
的代码的近似值。如您所见,没有魔术:
internal void InternalRemoveNode(LinkedListNode<T> node)
{
...
if ( node.next == node)
head = null;
else
{
node.next.prev = node.prev;
node.prev.next = node.next;
if ( head == node)
head = node.next;
}
node.Invalidate();
count--;
version++;
}
进一步阅读
Reference types (C# Reference)
C#中有两种类型:引用类型和值类型。 引用类型的变量存储对其数据(对象)的引用, 而值类型的变量直接包含其数据。用 引用类型,两个变量可以引用同一对象; 因此,对一个变量的运算会影响所引用的对象 通过另一个变量。对于值类型,每个变量都有其自己的 数据的副本,并且不可能对一个数据进行操作 会影响其他变量的变量(除非是in,ref和out 参数变量参见in,ref和out参数修改器。)