【问题标题】:I would like not to use root as global我不想将 root 用作全局
【发布时间】:2015-05-19 13:25:59
【问题描述】:

您好,我正在编写 avl 树,但有一个问题。我目前有一个全局根,因为我在课堂上和 main 中都使用它,我怎么能在没有全局的情况下编写它?

struct avl_node {
    int data;
    struct avl_node *left;
    struct avl_node *right;
}*root;

class avlTree {
    public:
        int height(avl_node *temp)
        {
            int h = 0;
            if (temp != NULL)
            {
                int l_height = height (temp->left);
                int r_height = height (temp->right);
                int max_height = max (l_height, r_height);
                h = max_height + 1;
            }
            return h;
        }

        int diff(avl_node *temp)
        {
            int l_height = height (temp->left);
            int r_height = height (temp->right);
            int b_factor= l_height - r_height;
            return b_factor;
        }

        avl_node *rr_rotation(avl_node *parent)
        {
            avl_node *temp;
            temp = parent->right;
            parent->right = temp->left;
            temp->left = parent;
            return temp;
        }       

        avl_node *ll_rotation(avl_node *parent)
        {
            avl_node *temp;
            temp = parent->left;
            parent->left = temp->right;
            temp->right = parent;
            return temp;
        }

        avl_node *lr_rotation(avl_node *parent)
        {
            avl_node *temp;
            temp = parent->left;
            parent->left = rr_rotation (temp);
            return ll_rotation (parent);
        }

        avl_node *rl_rotation(avl_node *parent)
        {
            avl_node *temp;
            temp = parent->right;
            parent->right = ll_rotation (temp);
            return rr_rotation (parent);
        }

        avl_node* balance(avl_node *temp)
        {
            int bal_factor = diff (temp);
            if (bal_factor > 1)
            {
                if (diff (temp->left) > 0)
                    temp = ll_rotation (temp);
                else
                    temp = lr_rotation (temp);
            }
            else if (bal_factor < -1)
            {
                if (diff (temp->right) > 0)
                    temp = rl_rotation (temp);
                else
                    temp = rr_rotation (temp);
            }
            return temp;
        }

        avl_node* insert(avl_node *root, int value)
        {
            if (root == NULL)
            {
                root = new avl_node;
                root->data = value;
                root->left = NULL;
                root->right = NULL;
                return root;
            }
            else if (value < root->data)
            {
                root->left = insert(root->left, value);
                root = balance (root);
            }
            else if (value >= root->data)
            {
                root->right = insert(root->right, value);
                root = balance (root);
            }
            return root;
        }

        void display(avl_node *ptr, int level)
        {
            int i;
            if (ptr!=NULL)
            {
                display(ptr->right, level + 1);
                printf("\n");
                if (ptr == root)
                    cout<<"Root -> ";
                for (i = 0; i < level && ptr != root; i++)
                    cout<<"        ";
                cout<<ptr->data;
                display(ptr->left, level + 1);
            }
        }

        void inorder(avl_node *tree)
        {
            if (tree == NULL)
                return;
            inorder (tree->left);
            cout<<tree->data<<"  ";
            inorder (tree->right);
        }

        void preorder(avl_node *tree)
        {
            if (tree == NULL)
                return;
            cout<<tree->data<<"  ";
            preorder (tree->left);
            preorder (tree->right);
        }

        void postorder(avl_node *tree)
        {
            if (tree == NULL)
                return;
            postorder ( tree ->left );
            postorder ( tree ->right );
            cout<<tree->data<<"  ";
        }

        avlTree()
        {
            root = NULL;
        }
};


int main()
{
    int choice, item;
    avlTree avl;
    while (1)
    {
        cout<<"\n---------------------"<<endl;
        cout<<"AVL Tree Implementation"<<endl;
        cout<<"\n---------------------"<<endl;
        cout<<"1.Insert Element into the tree"<<endl;
        cout<<"2.Display Balanced AVL Tree"<<endl;
        cout<<"3.InOrder traversal"<<endl;
        cout<<"4.PreOrder traversal"<<endl;
        cout<<"5.PostOrder traversal"<<endl;
        cout<<"6.Exit"<<endl;
        cout<<"Enter your Choice: ";
        cin>>choice;
        switch(choice)
        {
            case 1:
                system("cls");
                cout<<"Enter value to be inserted: ";
                cin>>item;
                root = avl.insert(root, item);
                break;
            case 2:
                system("cls");
                if (root == NULL)
                {
                    cout<<"Tree is Empty"<<endl;
                    continue;
                }
                cout<<"Balanced AVL Tree:"<<endl;
                avl.display(root, 1);
                break;
            case 3:
                system("cls");
                cout<<"Inorder Traversal:"<<endl;
                avl.inorder(root);
                cout<<endl;
                break;
            case 4:
                system("cls");
                cout<<"Preorder Traversal:"<<endl;
                avl.preorder(root);
                cout<<endl;
                break;
            case 5:
                system("cls");
                cout<<"Postorder Traversal:"<<endl;
                avl.postorder(root);    
                cout<<endl;
                break;
            case 6:
                exit(1);    
                break;
            default:
                system("cls");
                cout<<"Wrong Choice"<<endl;
        }
    }
    return 0;
}

【问题讨论】:

  • 为什么root 是一个节点而不是avlTree(应该包含一个根节点)?然后大多数函数在包含的root 上运行,而不需要参数。
  • 我有点理解你的意思,但我对如何实现它一无所知。
  • 使root成为班级成员:class avlTree{ struct avl_node{...} *root; public: ...methods};
  • @Bogdan 面向对象编程的基础知识之一:encapsulation,如“一种有助于将数据与操作该数据的方法(或其他函数)捆绑在一起的语言结构。”。
  • @CiaPan 将 root 设置为类的成员不会解决它,因为我在 main 中再次使用 root ? crashmstr 好的。

标签: c++ avl-tree


【解决方案1】:

您不应在main() 中显式使用树的root,并且通常在树的方法之外。要实现这一点,只需制作方法

    avl_node* insert(avl_node *where, int value)

在一个类中私有(或至少受保护)并添加一个公共接口:

    void insert(int value)
    {
        root = insert(root, value);
    }

然后在 main 中,您只需调用即可添加项目

    avlTree tree;

    ....
    tree.insert(item);

编辑以回答评论中提出的问题。

displayinorder 等函数的处理方式应与 insert 相同:声明一个公共的、无参数的函数来启动操作,并声明一个带参数的受保护方法以递归执行它:

public:
    void display()     { display(root, 0); }
    void inorder()     { inorder(root); }
    .....

protected:
    void display(avl_node *node, int level)
    {
        if (node!=NULL)
        {
            display(node->right, level + 1);
            if (node == root)
                cout << "Root -> ";
            else
                cout << "        ";
            cout << setw(5*level) << "" << node->data << endl;
            display(node->left, level + 1);
        }
    }

    void inorder(avl_node *node)
    {
        if (node)
        {
            inorder (node->left);
            cout << node->data << "  ";
            inorder (node->right);
        }
    }

然后使用:

tree.display();
tree.inorder();

【讨论】:

  • 谢谢,现在它确实更有意义了。我只有一个问题,我可以如何处理 in/post/pre 订单和停止使用 root 作为参数的显示。
  • 谢谢,反正我自己做了,但我会看看你的解释
猜你喜欢
  • 1970-01-01
  • 2013-12-17
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-04
  • 2013-07-13
相关资源
最近更新 更多