试图插入Avl树

时间:2014-02-23 23:55:51

标签: data-structures binary-tree nodes insert-update avl-tree

我正在尝试为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
};

1 个答案:

答案 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 - 但你似乎已经将这个想法差不多了。您需要在概念上进行更改的唯一方法是根据刚插入的密钥进行平衡。你不是 - 你根据树的形状进行平衡,你可以从每个子树的平衡因子得到它。