[英]Binary Search Tree--Inserting a Node
我正在嘗試實現 function 以將節點插入二叉搜索樹。 我正在使用以下代碼,但是當我嘗試打印到屏幕時,我看到的只是“root =1”。 關於我做錯了什么的任何建議?
#include <iostream>
class BTNode {
public:
int item;
BTNode *left;
BTNode *right;
BTNode(int i, BTNode *l=nullptr, BTNode *r=nullptr):item(i),left(l),right(r){}
};
BTNode *root = nullptr;
void insert(int i) {
if (root==nullptr)
root=new BTNode(i);
else if(i<root->item){
root=root->left;
insert(i);
}
else{
root=root->right;
insert(i);
}
}
int main()
{
insert (5);
insert (10);
insert (1);
if (root)
{
std::cout << "root = " << root->item << std::endl;
if (root->left)
std::cout << "root->left = " << root->left->item << std::endl;
if (root->right)
std::cout << "root->right = " << root->right->item << std::endl;
}
return 0;
}
你的代碼效果如下
您可以通過這種方式實現插入 function,它通常是 BTNode class 的成員 function,這就是為什么我將它們稱為私有/公共,但由於您選擇將它們實現為 function 在 class 之外,我將保持這種方式。
首先你有一個公共插入 function
void insert(int i){
insert( i,root);// call the private function. see below
}
其次你有一個私有插入 function (注意指針變量應該通過引用傳遞,否則它會改變指針的副本)
void insert(int i,BTNode *& t){
if(t==nullptr)t=new Node(i);
else if(i<t->item)insert(i,t->left);
else insert(i,t->right);
}
我在下面寫下了代碼。
BTNode *root = nullptr;
BTNode* insert_node(int ivalue, BTNode* _parent) {
if (_parent == nullptr) {
return _parent = new BTNode(ivalue);
}
else if (ivalue<_parent->item) {
_parent->left = insert_node(ivalue, _parent->left);
}
else {
_parent->right = insert_node(ivalue, _parent->right);
}
return nullptr;
}
void insert(int i) {
BTNode*newnode = insert_node(i, root);
if (newnode)root = newnode;
}
int main()
{
insert(5);
insert(10);
insert(1);
//insert(2);
//insert(4);
if (root)
{
std::cout << "root = " << root->item << std::endl;
if (root->left)
std::cout << "root->left = " << root->left->item << std::endl;
if (root->right)
std::cout << "root->right = " << root->right->item << std::endl;
}
return 0;
}
您的insert
function 正確地將新節點添加到樹中。 然而,作為一個副作用,它有時會改變全局變量root
以指向根的左節點或右節點,這樣樹的 rest 就會丟失。 你的insert
function 不應該改變根,除非root == nullptr
。
因此,我建議您重寫 function insert
,使其根本不使用root
,而是接收指向該節點的指針作為 function 參數。 該指針必須通過引用傳遞,而不是值傳遞,因為 function insert
必須能夠更改傳遞的實際指針,如果它是nullptr
的話。 為了實現這一點,您可以將 function 原型更改為以下內容:
void insert( BTNode &*pp_node, int i );
這也將使您的遞歸 function 調用正常工作,因為 function 現在可以像這樣重寫:
void insert( BTNode *&node, int i )
{
if ( node == nullptr )
node = new BTNode( i );
else if ( i < node->item )
insert( node->left, i );
else
insert( node->right, i );
}
您的 function main
必須這樣重寫:
int main()
{
insert( root, 5 );
insert( root, 10 );
insert( root, 1 );
[...]
}
但是,由於您不再需要將root
作為全局變量(因為它現在作為 function 參數傳遞),最好將其聲明為局部變量,如下所示:
int main()
{
BTNode *root = nullptr;
insert( root, 5 );
insert( root, 10 );
insert( root, 1 );
[...]
}
雖然這個問題的遞歸解決方案有效,但迭代解決方案會更有效。 因此,您可能希望像這樣重寫 function insert
:
void insert( BTNode **pp_node, int i )
{
while ( *pp_node != nullptr )
{
if ( i < (*pp_node)->item )
pp_node = &(*pp_node)->left;
else
pp_node = &(*pp_node)->right;
}
*pp_node = new BTNode( i );
}
該解決方案需要指向指針的指針(所謂的雙指針)而不是指向指針的引用,因為不能重新分配引用。
但是,由於insert
的 function 原型現在已經改變,您還必須相應地調整 function main
:
int main()
{
BTNode *root = nullptr;
insert( &root, 5 );
insert( &root, 10 );
insert( &root, 1 );
[...]
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.