[英]Binary Search Tree Remove
目前,我正在使用C ++在二叉搜索樹上工作,已經達到必須編寫remove / delete函數的階段(使用遞歸方法, x = change(x)
)。 我有兩個選擇:
在要刪除的節點的父節點處停止;
到達要刪除的節點,然后調用一個函數
返回父母
方法1:價格便宜,代碼更多
方法2:更少的代碼,更昂貴
您認為哪種方法更好,為什么?
我不同意這些是您僅有的兩個選擇。
我認為一個更簡單的解決方案是要求每個節點都應刪除它。 如果確定是,則將其刪除並返回應替換它的新節點。 如果決定不,則返回自身。
// pseudo code.
deleteNode(Node* node, int value)
{
if (node == NULL) return node;
if (node->value == value)
{
// This is the node I want to delete.
// So delete it and return the value of the node I want to replace it with.
// Which may involve some shifting of things around.
return doDelete(node);
}
else if (value < node->value)
{
// Not node. But try deleting the node on the left.
// whatever happens a value will be returned that
// is assigned to left and the tree will be correct.
node->left = deleteNode(node->left, value);
}
else
{
// Not node. But try deleting the node on the right.
// whatever happens a value will be returned that
// is assigned to right and the tree will be correct.
node->right = deleteNode(node->right, value);
}
// since this node is not being deleted return it.
// so it can be assigned back into the correct place.
return node;
}
最好的方法是遍歷要刪除的節點的父節點,然后刪除該子節點。 最終,您將始終訪問子節點,因為您始終必須確認子節點是您要刪除的節點。
我發現一般而言,編寫樹數據結構函數的最有效形式是以下偽代碼格式。
function someActionOnTree() {
return someActionOnTree(root)
}
function someActionOnTree (Node current) {
if (current is null) {
return null
}
if (current is not the node I seek) {
//logic for picking the next node to move to
next node = ...
next node = someActionOnTree(next node)
}
else {
// do whatever you need to do with current
// i.e. give it a child, delete its memory, etc
current = ...
}
return current;
}
此遞歸函數在數據結構的頂點集上遞歸。 對於算法的每次迭代,它要么尋找要在其上遞歸函數的節點,然后用該節點上算法迭代的值覆蓋對該節點的數據結構引用。 否則,它將覆蓋節點的值(並可能執行不同的邏輯集)。 最后,該函數返回對參數節點的引用,這對於覆蓋步驟至關重要。
這是我在C ++中為樹數據結構找到的通常最有效的代碼形式。 這些概念也適用於其他結構-您可以使用這種形式的遞歸,其中返回值始終是對數據結構的平面表示形式中的固定點的引用(基本上,總是返回您應該在現場找到的任何東西在看)。
這是對二進制搜索樹刪除功能的這種應用,以修飾我的觀點。
function deleteNodeFromTreeWithValue( value ) {
return deleteNodeFromTree(root, value)
}
function deleteNodeFromTree(Node current, value) {
if (current is null) return null
if (current does not represent value) {
if (current is greater than my value) {
leftNode = deleteNodeFromTree(leftNode, value)
} else {
rightNode = deleteNodeFromTree(rightNode, value)
}
}
else {
free current's memory
current = null
}
return current
}
顯然,還有許多其他方式可以編寫此代碼,但是根據我的經驗,這是最有效的方法。 注意,由於硬件已經緩存了節點,因此覆蓋指針實際上並不會影響性能。 如果您想提高搜索樹的性能,我建議您研究專門的樹,例如自平衡樹(AVL樹),B樹,紅黑樹等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.