数据结构avlTree C++实现

#include <iostream>
using namespace std;
template<class Comparable>
class AvlTree
{
public:
    AvlTree();
    AvlTree(const AvlTree& rhs);
    ~AvlTree();

public:
    const Comparable& findMin() const;   //find the minimum value
    const Comparable& findMax() const;   //find the maximum value
    bool contains(const Comparable& x) const; //Determine whether the tree contains x
    bool isEmpty() const;             //Determine whether the tree is empty
    void printTree() const;           //print the binary Tree
    int size() const;                 //return the tree's size

    void makeEmpty();                 //make Avl tree empty
    void insert(const Comparable& x); //insert a value into Avl tree
    void remove(const Comparable& x); //remove a value from Avl tree

    const AvlTree& operator= (const AvlTree& rhs); //overload operator =
private:
    struct AvlNode
    {
        Comparable element;
        AvlNode* left;
        AvlNode* right;
        AvlNode* parent;
        AvlNode() {}
        AvlNode(const Comparable& theElem, AvlNode* lt, AvlNode* rt, AvlNode* pt, int ht = 0) : element(theElem), left(lt),
                                                                            right(rt), parent(pt), height(ht){}
        int height;
    };
    AvlNode* root; //define the root node
    void insert(const Comparable& x, AvlNode *&t, AvlNode *parent = NULL) const;
    void remove(const Comparable& x, AvlNode *&t);
    AvlNode* findMin(AvlNode* t) const;
    AvlNode* findMax(AvlNode* t) const;
    bool contains(const Comparable& x, AvlNode* t) const;
    void printTree(AvlNode* t) const;
    void makeEmpty(AvlNode *&t) const;
    AvlNode* clone(AvlNode *t) const;
    int height(AvlNode *t) const;
    void rotateWithLeftChild(AvlNode *&k2); //LL单旋转
    void doubleWithLeftChild(AvlNode *&k3); //LR双旋转
    void rotateWithRightChild(AvlNode *&k2); //RR单旋转
    void doubleWithRightChild(AvlNode *&k3); //RL单旋转
    int length;
};
template<class Comparable>
AvlTree<Comparable>::AvlTree() : length(0)
{
    root = new AvlNode(); //constructor construct a tree without subtree
    root = NULL;
}
template<class Comparable>
AvlTree<Comparable>::AvlTree(const AvlTree& rhs)
{
    root = new AvlNode();
    root = NULL;
    makeEmpty();
    root = clone(rhs.root);
    length = rhs.length;
}
template<class Comparable>
AvlTree<Comparable>::~AvlTree()
{
    makeEmpty();
}
template<class Comparable>
const Comparable& AvlTree<Comparable>::findMin() const
{
    return findMin(root)->element;
}
template<class Comparable>
const Comparable& AvlTree<Comparable>::findMax() const
{
    return findMax(root)->element;
}
template<class Comparable>
int AvlTree<Comparable>::size() const
{
    return length;
}
template<class Comparable>
bool AvlTree<Comparable>::contains(const Comparable& x) const
{
    return contains(x, root);
}
template<class Comparable>
bool AvlTree<Comparable>::isEmpty() const
{
    return root == NULL;
}
template<class Comparable>
void AvlTree<Comparable>::printTree() const
{
    printTree(root);
}
template<class Comparable>
void AvlTree<Comparable>::makeEmpty()
{
    makeEmpty(root);
    length = 0;
}
template<class Comparable>
void AvlTree<Comparable>::insert(const Comparable& x)
{
    insert(x, root);
    ++length;
}
template<class Comparable>
void AvlTree<Comparable>::remove(const Comparable& x)
{
    remove(x, root);
    --length;
}
template<class Comparable>
const AvlTree<Comparable>& AvlTree<Comparable>::operator= (const AvlTree& rhs)
{
    if(this != &rhs)
    {
        makeEmpty();
        root = clone(rhs.root);
        length = rhs.length;
    }
    return *this;
}
template<class Comparable>
void AvlTree<Comparable>::insert(const Comparable& x, AvlNode *&t, AvlNode *parent = NULL) const
{
    if(t == NULL)
        t = new AvlNode(x, NULL, NULL, parent);
    else if(x < t -> element)
    {
        insert(x, t -> left, t);
        if(height(t -> left) - height(t -> right) == 2)
        {
          if(x < t -> left -> element)
                 rotateWithLeftChild(t);
             else
                 doubleWithLeftChild(t);
        }
    }
    else if(t -> element < x)
    {
        insert(x, t -> right, t);
        if(height(t -> right) - height(t -> left) == 2)
        {
          if(x < t -> right -> element)
                doubleWithRightChild(t);
            else
                rotateWithRightChild(t);
        }
    }
    else
        ;        //do nothing
        t -> height = max(height(t -> left), height(t -> right)) + 1;
}
template<class Comparable>
void AvlTree<Comparable>::remove(const Comparable& x, AvlNode *&t)
{
    if (t == NULL)
        return;
    if(x < t -> element)
    {
        remove(x, t -> left);
        if(t != NULL)
            t -> height = max(height(t -> left), height(t -> right)) + 1;
        if(height(t -> right) - height(t -> left) == 2)
        {
            if(t -> right -> right -> height > t -> right -> left -> height)
            {
                rotateWithRightChild(t);
            }
            else
            {
                doubleWithRightChild(t);
            }
        }
    }
    else if(t -> element < x)
    {
        remove(x, t -> right);
        if(t != NULL)
        t -> height = max(height(t -> right), height(t -> left)) + 1;
        if(height(t -> left) - height(t -> right) == 2)
        {
            if(t -> left -> left -> height > t -> left -> right -> height)
            {
                rotateWithLeftChild(t);
            }
            else
{
                doubleWithLeftChild(t);
            }
        }
    }
    else if(t -> left != NULL && t -> right != NULL)
    {
        t -> element = findMin(t -> right) -> element;
        remove(t->element, t->right);
    }
    else
    {
        AvlNode *oldNode = t;
        AvlNode *oldParent = t -> parent;
        t = (t -> left != NULL) ? t -> left : t -> right;
        if(t != NULL)
        t -> parent = oldParent;
        delete oldNode;
    }
}
template<class Comparable>
typename AvlTree<Comparable>::AvlNode* AvlTree<Comparable>::findMin(AvlNode *t) const
{
    if(t == NULL)
        return NULL;
    if(t -> left == NULL)
        return t;
    return findMin(t -> left);
}
template<class Comparable>
typename AvlTree<Comparable>::AvlNode* AvlTree<Comparable>::findMax(AvlNode *t) const
{
    if(t == NULL)
        return NULL;
    if(t -> right == NULL)
        return t;
    return findMax(t -> right);
}
template<class Comparable>
bool AvlTree<Comparable>::contains(const Comparable& x, AvlNode* t) const
{
    if(t == NULL)
        return false;
    else if(x < t -> element)
        return contains(x, t -> left);
    else if(t -> element < x)
        return contains(x, t -> right);
  else
        return true;
}
template<class Comparable>
void AvlTree<Comparable>::makeEmpty(AvlNode*& t) const
{
    if(t != NULL)
    {
        makeEmpty(t -> left);
        makeEmpty(t -> right);
        delete t;
    }
    t = NULL;
}
template<class Comparable>
void AvlTree<Comparable>::printTree(AvlNode* t) const
{
    if(t != NULL)
    {
        cout << t ->element << "\t";
        printTree(t -> left);
        cout << endl;
        printTree(t -> right);
    }
}
template<class Comparable>
typename AvlTree<Comparable>::AvlNode* AvlTree<Comparable>::clone(AvlNode *t) const
{
    if(t == NULL)
        return NULL;
    return new AvlNode(t -> element, clone(t -> left), clone(t -> right), t -> parent);
}
template<class Comparable>
int AvlTree<Comparable>::height(AvlNode* t) const
{
    return (t == NULL) ? -1 : t -> height;
}
template<class Comparable>
void AvlTree<Comparable>::rotateWithLeftChild(AvlNode *&k2)
{
    AvlNode* k1 = k2 -> left;
    k2 -> left = k1 -> right;
    k1 -> right = k2;
    k1 -> parent = k2 -> parent;
    k2 -> parent = k1;
    k2 -> height = max(height(k2 -> left), height(k2 -> right)) + 1;
    k1 -> height = max(height(k1 -> left), k2 -> height) + 1;
    k2 = k1;
}
template<class Comparable>
void AvlTree<Comparable>::doubleWithLeftChild(AvlNode *&k3)
{
    rotateWithRightChild(k3 -> left);
    rotateWithLeftChild(k3);
}
template<class Comparable>
void AvlTree<Comparable>::rotateWithRightChild(AvlNode *&k2)
{
    AvlNode* k1 = k2 -> right;
    k2 -> right = k1 -> left;
    k1 -> left = k2;
    k1 -> parent = k2 -> parent;
    k2 -> parent = k1;
    k2 -> height = max(height(k2 -> left), height(k2 -> right)) + 1;
    k1 -> height = max(height(k1 -> right), k2 -> height) + 1;
    k2 = k1;
}
template<class Comparable>
void AvlTree<Comparable>::doubleWithRightChild(AvlNode *&k3)
{
    rotateWithLeftChild(k3 -> right);
    rotateWithRightChild(k3);
}
int main()
{
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 山东大学数据结构课程设计要求实现AVL树AVL树是一种自平衡二叉搜索树,具有良好的平衡性。在AVL树中,每个节点的左子树和右子树的高度差不超过1。这种平衡性使得AVL树的查找、插入和删除操作的时间复杂度都为O(logn),相较于其他平衡二叉搜索树如红黑树而言,AVL树的查找性能更好。 实现AVL树主要包括以下几个步骤: 1. 定义AVL树的节点结构,包含数据域和左右子节点指针。 2. 实现AVL树的插入操作。插入操作首先按照二叉搜索树的规则找到要插入的位置,然后进行平衡调整。插入操作的平衡调整包括修改各个节点的平衡因子,根据不同的情况进行树的旋转操作,以保证树的平衡性。 3. 实现AVL树的删除操作。删除操作首先按照二叉搜索树的规则找到要删除的节点,然后进行平衡调整。删除操作的平衡调整包括修改各个节点的平衡因子,并根据不同的情况进行树的旋转操作,以保证树的平衡性。 4. 实现AVL树的查找操作。查找操作按照二叉搜索树的规则进行,即根据节点的大小关系不断在左子树或右子树中查找,直到找到目标节点或者为空节点。 在实现AVL树的过程中,需要注意保持树的平衡性,并根据旋转操作的具体情况进行适当的调整。此外,还可以实现一些辅助函数,如计算节点的高度、更新节点的平衡因子等,以提高代码的可读性和维护性。 总之,山东大学数据结构课程设计要求实现AVL树,通过定义节点结构和实现插入、删除和查找操作,可以实现一个具有良好平衡性和高效性能的AVL树。 ### 回答2: 山东大学的数据结构课程设计中,我实现AVL树AVL树是一种平衡二叉搜索树,它的目的是保持树的平衡,以避免在搜索、插入和删除操作中产生较高的时间复杂度。AVL树通过在每个节点上维护一个平衡因子(即左子树高度减去右子树高度),来确保树的平衡。 在我的实现中,首先我定义了一个AVLNode结构体,它包含了存储在树节点中的数据以及两个指向左右子节点的指针。然后,我实现了一些基本操作函数,包括实现了插入函数、删除函数、查找函数等等。 在插入函数中,我通过递归地将新节点插入到树中,并在插入完成后更新每个节点的平衡因子。这样,如果平衡因子超过了允许的范围(例如-1到1之外),我就需要进行相应的旋转操作来恢复树的平衡。 在删除函数中,我首先找到要删除的节点,并按照BST的规则进行删除操作。删除后,我还需要更新其父节点及其祖先节点的平衡因子,并通过旋转操作来保持树的平衡性。 除了插入和删除操作,我还实现了一些其他的功能,例如查找最小值、查找最大值、查找后继节点、查找前驱节点等。 在整个实现过程中,我注重了代码的可读性和效率。我使用了递归来处理树的节点,利用平衡因子来判断树的平衡性,采用适当的旋转操作来维持树的平衡。通过测试样例,我验证了实现的正确性和性能。 ### 回答3: AVL树是一种自平衡的二叉搜索树,它的设计旨在解决二叉搜索树在插入、删除等操作过程中可能导致不平衡的问题。 在山东大学数据结构课程设计中,我们可以采用以下步骤实现AVL树: 1. 首先,我们需要定义AVL树的节点结构,该结构包括左右孩子指针、平衡因子和关键字等信息。可以使用结构体来表示节点。 2. 接着,我们实现插入操作。当插入一个新的节点时,我们需要按照二叉搜索树的规则找到插入位置,并将节点插入到相应的位置。插入完成后,我们需要逐级向上更新每个节点的平衡因子,并检查是否需要进行旋转操作。 3. 为了保持树的平衡性,我们需要定义旋转操作。主要有四种旋转操作:左单旋、右单旋、左-右双旋和右-左双旋。这些旋转操作能够通过改变节点之间的链接关系,使树重新平衡。 4. 我们还需要实现删除操作。删除节点时,我们首先找到要删除的节点,并根据二叉搜索树的规则调整树的结构。删除完成后,同样需要逐级向上更新每个节点的平衡因子,并检查是否需要进行旋转操作。 5. 最后,我们需要实现一些辅助函数,如计算树的高度、查找最小值和最大值等。 在实现AVL树时,需要注意维护树的平衡性,并确保插入和删除操作的正确性。此外,可在实现过程中添加必要的错误处理、输入验证和合理的注释,以提高代码的稳定性和可读性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值