我正在尝试为Avl树创建一个插入方法,但我的节点的结构和顺序结果是不正确的。我无法找到我出错的地方。
这是我的方法 任何形式的帮助将不胜感激
模板
void AvL<T>::insert(string val, T k)
{
if (head == NULL) {
head = new AvLNode<T>(val, k);
} else {
put(head, val, k);
}
}
template <class T>
void AvL<T>::put(AvLNode<T>* root,string val,T key1) {
if (root->key > key1) {
if (root->left != NULL) {
put(root->left, val, key1);
Balance(root, key1);
} else {
root->left = new AvLNode<T>(val, key1);
root->bf = nodeHeight(root->left) - nodeHeight(root->right);
root->left->parent = root;
}
} else {
if (root->right != NULL) {
put(root->right, val, key1);
Balance(root, key1);
} else {
root->right = new AvLNode<T>(val, key1);
root->bf = nodeHeight(root->left) - nodeHeight(root->right);
root->right->parent = root;
}
}
}
template<class T>
void AvL<T>::Balance(AvLNode<T>* root, T key1)
{ root->bf = nodeHeight(root->left) - nodeHeight(root->right);
if (root->bf < -1 && key1 > root->right->key) {
cout << "here1 ";
LeftRotate(root);
} else if (root->bf > 1 && key1 < root->left->key) {
cout << "here2 ";
RightRotate(root);
} else if (root->bf < -1 && key1 < root->right->key) {
RightRotate(root->right);
cout << "here3 ";
LeftRotate(root);
} else if (root->bf > 1 && key1 > root->left->key) {
LeftRotate(root->left);
cout << "here4 ";
RightRotate(root);
}
}
template<class T>
void AvL<T>::RightRotate(AvLNode<T>* node)
{
AvLNode<T>* node1 = node->left;
node->left = node1->right;
node1->right = node;
node->bf = nodeHeight(node->left) - nodeHeight(node->right);
node1->bf = nodeHeight(node1->left) - nodeHeight(node1->right);
node = node1;
}
template<class T>
void AvL<T>::LeftRotate(AvLNode<T>* node)
{
AvLNode<T>* node1 = node->right;
node->right = node1->left;
node1->left = node;
node->bf = nodeHeight(node->left) - nodeHeight(node->right);
node1->bf = nodeHeight(node1->left) - nodeHeight(node1->right);
node = node1;
}
template<class T>
int AvL<T>::nodeHeight( AvLNode<T> *n)
{
int lheight=0;
int rheight=0;
int h = 0;
if (n == NULL)
{
return -1;
} else {
lheight = nodeHeight(n->left);
rheight = nodeHeight(n->right);
h = 1+max(lheight,rheight);
return h;
}
}
我的.h文件
template <class T>
struct AvLNode
{
string value;
T key;
AvLNode *parent; // pointer to parent node
AvLNode *left; // pointer to left child
AvLNode *right; // pointer to right child
int bf; // Balance factor of node
AvLNode(string Val, T k)
{
this->value = Val;
this->key = k;
this->parent = NULL;
this->left = NULL;
this->right = NULL;
bf = 0;
}
};
template <class T>
class AvL
{
AvLNode<T> *head;
public:
// Constructor
AvL();
// Destructor
~AvL();
// Insertion Function
void insert(string val, T k); // inserts the given key value pair into the tree
void Balance(AvLNode<T>* node, T key1);
void delete_node(T k); // deletes the node for the given key
void RightRotate(AvLNode<T>* node);
void LeftRotate(AvLNode<T>* node);
void put(AvLNode<T>* root,string val,T key1);
int nodeHeight(AvLNode<T> *n); // returns height of the subtree from given node
};
答案 0 :(得分:0)
您的余额功能有误。由于您已经将新节点插入到树中,因此您无需再担心Balance()
中的密钥 - 因此原型应如下所示:
template<class T>
void AvL<T>::Balance(AvLNode<T>* root);
你现在这样做的方式似乎是试图根据你刚刚插入的键进行平衡 - 这是没有必要的!您可以根据节点的平衡因子平衡树 - 这是如何。
template<class T>
void AvL<T>::Balance(AvLNode<T>* root) {
if (root->bf > 1) {
if (root->left->bf == -1) LeftRotate(root->left);
RightRotate(root);
} else if (root->bf < -1) {
if (root->right->bf == 1) RightRotate(root->right);
LeftRotate(root);
}
}
你可以阅读更多相关信息here - 但你似乎已经将这个想法差不多了。您需要在概念上进行更改的唯一方法是根据刚插入的密钥进行平衡。你不是 - 你根据树的形状进行平衡,你可以从每个子树的平衡因子得到它。