我的问题:嗨,method-LinkedList.Remove(LinkedListNode n)是否更改了LinkedList中其他元素的引用?
应用程序有点复杂,所以至少我会尝试解释我是如何到达这里的,但也许会让人感到困惑
我有一个存储引用的程序(来自的LinkedListNodes) LinkedList)到另一个可迭代类。在某些方面, 应用程序开始删除这些LinkedListNodes method-Remove(LinkedListNode节点)并从中删除此元素 我的类存储这些引用。它运行良好一段时间,但是 在某些方面它会松开我班上的一个参考,我得到了 当我想调用时,null引用(在myNode中) LinkeList.AddAfter(myNode,value),错误:“LinkedList节点 不属于当前LinkedList“。
修改
我正在翻译笔记等等...... 所以我使用BinarySearchTree进行快速搜索,使用LinkedList进行正常迭代,使用QUEUE进行删除旧元素。
这是插入我的Tree类:
public Node Insert(DictionaryPair dictionaryPair, LinkedList<DictionaryPair> dictionary)
{
Node currentNode = nodeRoot;
while (true)
{
if (currentNode == null) //if i inserting 1st element
{
nodeRoot = new Node(); //creating node(root)
dictionary.AddFirst(dictionaryPair); //inserting into Linked list on 1st place
nodeRoot.dictionaryNode = dictionary.First; //and taking a reference
return nodeRoot; //end while
}
else if (currentNode.dictionaryNode.Value.CompareTo(dictionaryPair) >= 0)
{ //sending element into left
if (currentNode.left == null) // and is empty
{
currentNode.left = new Node(); //creating new node
currentNode.left.myParent = currentNode; //reference to parent
currentNode.left.dictionaryNode = dictionary.AddBefore(currentNode.dictionaryNode, dictionaryPair);
//and inserting into dictionary (Before) current node and save the refence on it to left
return currentNode.left; //end while
}
else
{ //or shift to left
currentNode = currentNode.left;
}
}
else
{ //sending element into right
if (currentNode.right == null) // is null
{
currentNode.right = new Node(); //create new node
currentNode.right.myParent = currentNode; //reference on parent
currentNode.right.dictionaryNode = dictionary.AddAfter(currentNode.dictionaryNode, dictionaryPair);
//and insert into dictionary (After) current node and save the refence on it to right
return currentNode.right; //endwhile
}
else
{ //or shift to right side
currentNode = currentNode.right;
}
}
}
}
类节点:
public LinkedListNode<DictionaryPair> dictionaryNode;
public Node left;
public Node right;
public Node myParent;
我可以在我的节点上调用delete方法:
public LinkedListNode<DictionaryPair> DeleteMe()
{
LinkedListNode<DictionaryPair> deletedNode = this.dictionaryNode;
if (this.left == null && this.right == null)
{ //Delete leaf
if(myParent.left == this)
{
myParent.left = null;
}
else // else if(myParent.right == this)
{
myParent.right = null;
}
}
else if (this.left != null && this.right == null)
{
this.right = this.left.right;
this.dictionaryNode = this.left.dictionaryNode;
this.left = this.left.left;
}
else if (this.left == null && this.right != null)
{
this.left = this.right.left;
this.dictionaryNode = this.right.dictionaryNode;
this.right = this.right.right;
}
else
{ //on left and right are tries
Node currentNode = this.left; //throught the left side
bool oneCycle = false; //possibility of not iterating once thought the left side into the right (so it would be left)
while (currentNode.right != null)
{ //searching element most to the right
currentNode = currentNode.right;
oneCycle = true;
}
if (currentNode.left == null)
{ //i am leaf
if (oneCycle)
{
currentNode.myParent.right = null; //deleting refence on me
this.dictionaryNode = currentNode.dictionaryNode; //and change a value
}
else
{
currentNode.myParent.left = null; //deleting refence on me
this.dictionaryNode = currentNode.dictionaryNode; //and change a value
}
}
else
{ //im not leaf
if (oneCycle)
{
currentNode.myParent.right = currentNode.left; //change refence on my tree
this.dictionaryNode = currentNode.dictionaryNode; //and change value
}
else
{
currentNode.myParent.left = currentNode.left; //change refence on my tree
this.dictionaryNode = currentNode.dictionaryNode; //and change value
}
}
}
return deletedNode;
}
这是我使用数组MyDictionary的主要类,它有
private LinkedList<DictionaryPair> data; //for iterating search
private Tree binarySearchTree; //for quick search
private Queue<Node> queue; //references on added nodes
//in binarySearchTree... they are ready to be deleted
private int maxCount;
private bool maxCountReached;
当我插入MyDictionary时,我调用了这个方法
public void Insert(DictionaryPair input)
{
if (!maxCountReached)
{
if (queue.Count() >= maxCount)
{
maxCountReached = true;
}
}
if (maxCountReached)
{
data.Remove(queue.Dequeue().DeleteMe());
}
queue.Enqueue(binarySearchTree.Insert(input, data));
}
答案 0 :(得分:1)
[...]方法LinkedList.Remove(LinkedListNode n)是否更改了LinkedList中其他[s]元素的引用?
当我们查看LinkedList.Remove
方法的source code时,我们发现除了调整prev
和next
指针之外,框架不会混淆其他元素(为了弥补删除造成的差距,并根据链表原则的定义。)
除了边境案例,它只是
node.next.prev = node.prev;
node.prev.next = node.next;
item
操作不会修改其他元素的对象(内部数据结构中的Remove
)。 Remove
操作本身所针对的对象也不会受到直接影响。当节点与列表分离时,如果没有其他生物对象保留引用,则它有资格进行垃圾回收。
您看到的例外是generated here:
if ( node.list != this) {
throw new InvalidOperationException(SR.GetString(SR.ExternalLinkedListNode));
}
如果此验证在AddAfter
中失败,则可能意味着:
LinkedList
的现有节点,例如先前从列表中删除的节点。在您发布的代码中,这将是currentNode.dictionaryNode
,并且我专注于调试时分配的行 LinkedList
实例的现有节点。答案 1 :(得分:0)
我在BinarySearchTree中实现了DeleteMe方法时发现了一个错误。我没有改变父节点对找到的currentNode下的节点的引用。但是谢谢你的帮助。祝你有美好的一天......