平衡二叉搜索树 (BST)
Balancing a Binary Search Tree (BST)
我正在尝试制作一个balance_bst(bstNode根(函数,但我正在努力实现。
我正在将该函数实现为模板函数,因为我的 bstNode 类是一个模板类。
这是我的(一些(代码:
template<class Item, class Key>
class bstNode{
public:
//Constructor
bstNode(const Item& init_data = Item(), const Key& init_key = Key(), bstNode<Item, Key>* l_child = NULL, bstNode<Item, Key>* r_child = NULL){
data_field = init_data;
key_field = init_key;
l_ptr = l_child;
r_ptr = r_child;
}
//Destructor
~bstNode(){
data_field = 0;
key_field = 0;
l_ptr = r_ptr = NULL;
}
//Basic Member Functions
bstNode<Item, Key>*& left( ) { return l_ptr; } //returns left child pointer by reference
bstNode<Item, Key>*& right( ) { return r_ptr; } //returns right child pointer by reference
bstNode<Item, Key>* left( ) const { return l_ptr; } //returns left child pointer by reference
bstNode<Item, Key>* right( ) const { return r_ptr; } //returns right child pointer by reference
const Item& data() const{ return data_field; } //returns reference to data_field
const Key& key()const { return key_field; }
Item& data() { return data_field; } //returns reference to data_field
Key& key() { return key_field; }
void set_data(const Item& new_data){ data_field = new_data; } //sets data_field to new_data
void set_key(const Key& new_key){ key_field = new_key; } //sets key_field to new_key
void set_left(bstNode* new_left){ l_ptr = new_left; } //sets left child pointer to new_left
void set_right(bstNode* new_right){ r_ptr = new_right; } //sets right child pointer to new_right
private:
bstNode<Item, Key> *l_ptr, //pointer to left child node
*r_ptr; //pointer to right child node
Item data_field;
Key key_field;
};
template<class Item, class Key>
void balance_bst(bstNode<Item, Key>*& root){ //unfinished
std::vector< bstNode<Item, Key>* > nodes;
sorter(root, nodes);
size_t i = nodes.size()/2; //size() divided by 2 will yield
//index of middle element of vector for
//odd-isized arrays and the greater of the
//middle two elements for an even-sized array
while(i>=0){
root->set_key(nodes[i]->key());
root->set_data(nodes[i]->data());
//.....MORE CODE HERE: recursive call??
}
}
template<class Item, class Key>
void sorter(bstNode<Item, Key>*& root, std::vector<bstNode<Item, Key>* >& tree_nodes){
if(root == NULL)
return;
sorter(root->left(), tree_nodes);
tree_nodes.push_back(root);
sorter(root->right(), tree_nodes);
}
我一直在搞砸实际的balance_bst函数,并认为递归是显而易见的解决方案,但我似乎无法解决这个问题......
排序器基本上使用排序处理算法将 BST 的元素插入到向量中。 因此,只要"root"是指向二叉搜索树根的指针(即节点左侧子树的所有键值都小于节点的键值,并且节点右侧子树的所有键值都大于节点(,那么插入向量的节点将以升序方式进行排序。
然后,为了创建一个平衡树,我将节点插入树根的向量中心,然后应该能够递归插入左右子节点,然后这些子节点将位于向量左半部分的中间和向量的右半部分的中间。
注意:我知道这是使用整数除法,也就是说,7/2 = 3,这将是大小为 7 的数组的中间元素的索引。 对于偶数大小的数组,上面实现的算法将在向量中间找到两个元素中较大者的索引。
无论如何,欢迎和鼓励任何建议或意见! 提前谢谢。
编辑:我要问的是,如何实现平衡二叉搜索树的功能?(平衡的 BST 是给定节点数的最小深度的 BST。
平衡二叉搜索树也称为 AVL 树.
此维基百科链接对解决平衡问题有很好的解释。
我发现平衡树的最简单方法是在插入过程中。这是一个带有辅助函数(用于各种旋转情况(和一个 AVLNode 类的递归插入。
bool avl_insert(AVLNode*& subRoot, const int &newData, bool &taller)
{
bool result = true;
if(!subRoot){
subRoot = new AVLNode(newData);
taller = true;
}
else if(newData == subRoot->getData()){
result = false;
taller = false;
}
else if(newData < subRoot->getData()){
result = avl_insert(subRoot->getLeft(), newData, taller);
if(taller)
switch(subRoot->getBalance()){
case -1:
left_balance(subRoot);
taller = false;
break;
case 0:
subRoot->setBalance(-1);
break;
case 1:
subRoot->setBalance(0);
taller = false;
break;
}
}
else{
result = avl_insert(subRoot->getRight(), newData, taller);
if(taller)
switch(subRoot->getBalance()){
case -1:
subRoot->setBalance(0);
taller = false;
break;
case 0:
subRoot->setBalance(1);
break;
case 1:
right_balance(subRoot);
taller = false;
break;
}
}
return result;
}
帮助程序函数
void right_balance(AVLNode *&subRoot)
{
AVLNode *&right_tree = subRoot->getRight();
switch(right_tree->getBalance()){
case 1:
subRoot->setBalance(0);
right_tree->setBalance(0);
rotate_left(subRoot); break;
case 0:
cout<<"WARNING: program error in right_balance"<<endl; break;
case -1:
AVLNode *subTree = right_tree->getLeft();
switch(subTree->getBalance()){
case 0:
subRoot->setBalance(0);
right_tree->setBalance(0);break;
case -1:
subRoot->setBalance(0);
right_tree->setBalance(1); break;
case 1:
subRoot->setBalance(-1);
right_tree->setBalance(0);break;
}
subTree->setBalance(0);
rotate_right(right_tree);
rotate_left(subRoot); break;
}
}
void left_balance(AVLNode *&subRoot)
{
AVLNode *&left_tree = subRoot->getLeft();
switch(left_tree->getBalance()){
case -1:
subRoot->setBalance(0);
left_tree->setBalance(0);
rotate_right(subRoot); break;
case 0:
cout<<"WARNING: program error in left_balance"<<endl; break;
case 1:
AVLNode *subTree = left_tree->getRight();
switch(subTree->getBalance()){
case 0:
subRoot->setBalance(0);
left_tree->setBalance(0);break;
case -1:
subRoot->setBalance(0);
left_tree->setBalance(1); break;
case 1:
subRoot->setBalance(-1);
left_tree->setBalance(0);break;
}
subTree->setBalance(0);
rotate_left(left_tree);
rotate_right(subRoot); break;
}
}
void rotate_left(AVLNode *&subRoot)
{
if(subRoot == NULL || subRoot->getRight() == NULL)
cout<<"WARNING: program error detected in rotate_left"<<endl;
else{
AVLNode *right_tree = subRoot->getRight();
subRoot->setRight(right_tree->getLeft());
right_tree->setLeft(subRoot);
subRoot = right_tree;
}
}
void rotate_right(AVLNode *&subRoot)
{
if(subRoot == NULL || subRoot->getLeft() == NULL)
cout<<"WARNING: program error detected in rotate_left"<<endl;
else{
AVLNode *left_tree = subRoot->getLeft();
subRoot->setLeft(left_tree->getRight());
left_tree->setRight(subRoot);
subRoot = left_tree;
}
}
AVLNode 类
class AVLNode
{
public:
AVLNode()
{
previous = NULL;
next = NULL;
}
AVLNode(int newData){
data = newData;
previous = NULL;
balance=0;
next = NULL;
}
~AVLNode(){}
void setBalance(int b){balance = b;}
int getBalance(){return balance;}
void setRight(AVLNode* newNext){next = newNext;}
void setLeft(AVLNode* newPrevious){previous = newPrevious;}
AVLNode* getRight() const{return next;}
AVLNode* getLeft() const{return previous;}
AVLNode*& getRight(){return next;}
AVLNode*& getLeft(){return previous;}
int getData() const{return data;}
int& getData(){return data;}
void setData(int newData){data = newData;}
void setHeight(int newHeight){ height = newHeight;}
int getHeight(){return height;}
private:
AVLNode* next;
AVLNode* previous;
int balance;
int height;
int data;
};
希望这有帮助!
相关文章:
- 有根的二进制搜索树.保留与其父级的链接
- 正在尝试重载二进制搜索树分配运算符
- 使用C++创建特殊的二叉搜索树
- 在递归二叉搜索树中搜索
- 在二叉搜索树中插入时出现分段错误
- C++二叉搜索树模板从函数返回节点
- 我可以在没有堆栈的情况下在二叉搜索树中实现迭代器吗?
- 在二叉搜索树C++中计算平均值
- 在字符串的二叉搜索树中搜索子字符串 - C++
- 在二叉搜索树中插入新元素
- 如何打印在二叉搜索树中找到的数据?
- 查找存储在二叉搜索树的所有非叶子中的数据总和?(返回整数的独立递归函数
- 这是一个二叉搜索树吗?黑客排名问题
- 二叉搜索树 - 实现"search"函数
- 二叉搜索树 (BST) 返回左子被视为函数,不理解
- 平衡二叉搜索树 (BST)
- 测试二叉搜索树(BST)的遍历
- c++迭代插入到二叉搜索树BST
- 二叉搜索树- c++ BST补充说明更改
- 二叉搜索树(BST)