如何進行搜索二叉樹分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
一、搜索二叉樹
1、定義:它是一棵排序二叉樹,可為空樹。
2、性質:
每個節點都有一個作為搜索依據的關鍵碼(key),所有節點的關鍵碼互不相同;
左子樹上所有節點的關鍵碼(key)都小于根節點的關鍵碼(key);
右子樹上所有節點的關鍵碼(key)都大于根節點的關鍵碼(key);
左、右子樹都是二叉搜索樹。
二、源代碼
1、定義節點
template<class K,class V>
struct BSTreeNode
{
BSTreeNode<K,V> *_left;//左節點
BSTreeNode<K,V> *_right;//右節點
K _key;//節點權值
V _value;
BSTreeNode(const K& key,const V& value)
:_key(key)
,_value(value)
,_left(NULL)
,_right(NULL)
{}
};2、搜索二叉樹及其相關實現
template<class K,class V>
class BSTree
{
typedef BSTreeNode<K,V> Node;
public:
BSTree()
:_root(NULL)
{}
//非遞歸
Node* Find(const K& key)
{
return _Find(_root,key);
}
bool Insert(const K& key,const V& value)
{
return _Insert(_root,key,value);
}
bool Remove(const K& key)
{
return _Remove(_root,key);
}
//遞歸
bool InOrder() //中序遍歷 --> 有序序列
{
return _InOrder(_root);
cout<<endl;
}
Node* FindR(const K& key)
{
return _FindR(_root,key);
}
bool InsertR(const K& key,const V& value)
{
return _InsertR(_root,key,value);
}
bool RemoveR(const K& key)
{
return _RemoveR(_root,key);
}
protected:
//非遞歸
Node* _Find(Node *root,const K& key)
{
if(root == NULL) return NULL;
Node *cur=root;
if(cur->_key > key)
{
cur=cur->_right;
}
else if(cur->_key < key)
{
cur=cur->_left;
}
else
{
return cur;
}
return NULL;
}
bool _Insert(Node *&root,const K& key,const V& value)
{
if(root == NULL)
{
root=new Node(key,value);
return true;
}
Node *cur=root;
Node *parent=NULL;
while(cur)
{
if(cur->_key < key)
{
parent=cur;
cur=cur->_right;
}
else if(cur->_key > key)
{
parent=cur;
cur=cur->_left;
}
else
return false;
}
if(parent->_key < key)
{
parent->_right=new Node(key,value);
parent->_right=parent;
}
else
{
parent->_left=new Node(key,value);
parent->_left=parent;
}
return true;
}
bool _Remove(Node*& root,const K& key )
{
if(root == NULL) return false;
Node *cur=root;
Node *parent=NULL;
while(cur) //找節點
{
if(cur->_key > key)
{
parent=cur;
cur=cur->_left;
}
else if(cur->_key < key)
{
parent=cur;
cur=cur->_right;
}
else //找到節點
{
if(cur->_left == NULL)//左為空
{
if(parent == NULL)
root=cur->_right;
else if(parent->_left == cur)
parent->_left=cur->_right;
else
parent->_right=cur->_right;
}
else if(cur->_right == NULL)//右為空
{
if(parent == NULL)
root=cur->_left;
else if(parent->_left == cur)
parent->_left=cur->_left;
else
parent->_right=cur->_left;
}
else //左右都不為空
{
Node *parent=cur;
Node *left=cur->_right;//右子樹的最左節點
while(left->_left)
{
left=left->_left;
}
cur->_key=left->_key;//替換結點
cur->_value=left->_value;
if(parent->_left == left)
parent->_left=left->_left;
else
parent->_right=left->_right;
delete left;
}
}
return true;
}
return false;
}
//遞歸
bool _InOrder(Node *root)
{
if(root == NULL) return false;
_InOrder(root->_left);
cout<<root->_left<<" ";
_InOrder(root->_right);
return true;
}
Node* _FindR(Node *root,const K& key)
{
if(root == NULL) return NULL;
if(root->_key == key)
return root;
else if(root->_key > key)
return _FindR(root->_left,key);
else
return _FindR(root->_right,key);
}
bool _InsertR(Node *root,const K& key,const V& value)
{
if(root == NULL)
{
root=new Node(key,value);
return true;
}
if(root->_key > key)
return _InsertR(root->_left,key,value);
else if(root->_key < key)
return _InsertR(root->_right,key,value);
else
return false;
}
bool _RemoveR(Node *root,const K& key)
{
if(root == NULL) return false;
if(root->_key > key)
return _RemoveR(root->_left,key);
else if(root->_key < key)
return _RemoveR(root->_right,key);
else //找到節點
{
Node *del=NULL;
if(root->_left == NULL)
root=root->_right;
else if(root->_right == NULL)
root=root->_left;
else
{
Node *parent=NULL;
Node *left=root;
while(left->_left)
{
parent=left;
left=left->_left;
}
root->_key=left->_key;
root->_value=left->_value;
del=left;
if(parent->_left == left)
parent->_left=left->_left;
else
parent->_right=left->_right;
delete del;
return true;
}
}
return false;
}
protected:
Node *_root;
};3、總結:
搜索二叉樹是一棵排序二叉樹,可為空樹。它的每一個節點都遵從搜索二叉樹的性質。
搜索二叉樹的中序遍歷后為升序序列;其查找根據key值以及性質進行;其插入需先根據其key值找到插入的節點,隨后添加節點,另外其key值唯一;
其刪除節點時,需分3種情況:
(1)僅左為空;
(2)僅右為空;
(3)該節點左右皆不為空。
刪除該節點,即需 找到 右子樹的最左節點 或 左子樹的最右節點,作為替換結點。
看完上述內容,你們掌握如何進行搜索二叉樹分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。