二进制搜索树使用类

时间:2017-06-10 18:36:45

标签: c++ tree binary-search-tree

我一直在尝试使用类来实现二叉搜索树。每次我尝试编译并运行程序时,程序结束。我已经尝试过很多东西,例如让* root公共访问它,因此我可以更新根,但不知何故它每次都变为null。 帮助将不胜感激。 这是我的大学项目。

#include <iostream>
using namespace std;
class tree;
class Node {
    friend class tree;
private:
    Node *lchild,*rchild;
    int data;
public:
    Node (int x) {
        data = x;
        lchild = rchild = NULL;
    }
};
class tree {
protected:
    Node* root;
    void inorder(const Node* root)const;
public:
    tree () {
        root = NULL;
    }
    bool insert(int item);
    void inorder() const {inorder(root);};
    Node* getroot() {
        return root;
    }
};
bool tree :: insert(int item) {
    if (root == NULL) {
        Node *temp = new Node(item);
        root = temp;
        return (bool) root;
    }
    if (item < root -> data) {
        insert(item);
    }
    if (item > root -> data) {
        insert(item);
    }
    else if (item == root -> data) {
        cout<<"Duplicate";
        exit (0);
    }
    return (bool) root;
}
void tree :: inorder(const Node *root)const {
    if (root != NULL) {
        inorder(root -> lchild);
        cout<<root -> data;
        inorder(root -> rchild);
    }
}
int main()
{
    tree obj1;
    obj1.insert(3);
    //obj1.insert(4);
    obj1.insert(1);
    //obj1.insert(5);
    obj1.inorder();
}

3 个答案:

答案 0 :(得分:0)

root一次又一次获得NULL的原因是它实际上从未将其值更改为NULL之外的其他值。 也许您在修复其他问题的过程中在代码中引入了这种行为;但是你在构造函数中指定了root=NULL;之后,当您在obj.root1 = ...中返回root时,只会分配getroot() { return root; }。此外,您在插入函数中传递Node *root作为参数;请注意,名为root的此局部变量隐藏了数据成员root,因此这些函数中的root->...将始终寻址局部变量而不是数据成员。

在使用代码进行重新设计之前,我建议调整设计,然后调整代码;我很确定这些错误会消失。我建议如下调整class tree的界面并编写代码。

成员函数inorder()应为const,表示它不会改变对象的状态。请注意,const - 成员函数可以 - 与其他非静态成员函数相比 - 在const - 对象上调用。

class Node {
    friend class tree;
private:
    Node *lchild,*rchild;
    int data;
public:
    Node (int x) {
        data = x;
        lchild = rchild = NULL;
    }
};
class tree {
public:
    tree () { root = NULL; }
    bool insert(int item) { return insert(item,root); };
    void inorder() const { inorder(root);};

protected:
    Node* root;
    void inorder(const Node* curr) const;
    bool insert(int item, Node* curr);

};

bool tree :: insert(int item, Node *currNode) {
    if (root == NULL) {
        root = new Node(item);
        return true;
    }
    else if (item < currNode->data) {
        if (currNode->lchild == NULL) {
            currNode->lchild = new Node(item);
            return true;
        }
        else {
            return insert(item, currNode->lchild);
        }
    }
    else if (item > currNode->data) {
        if (currNode->rchild == NULL) {
            currNode->rchild = new Node(item);
            return true;
        }
        else {
            return insert(item, currNode->rchild);
        }
    }
    else // item == currNode->data
        return false; // duplicate; do not insert
}

答案 1 :(得分:0)

/* Program to implement Binary Search Tree in c++ using classes and objects  */
#include<iostream>
#include<stdlib.h>
#include<cstdlib>
using namespace std;


struct Node {
    int data;
    Node* left;
    Node* right;
};

class BinaryTree {
    private:
        struct Node* root;
    public:
        BinaryTree() {
            root = NULL;
        }
        Node* createNode(int);
        Node* insertNode(Node*, int);
        Node* deleteNode(Node*, int);
        void inOrder(Node*);
        void preOrder(Node*);
        void postOrder(Node*);
        Node* findMinimum(Node*);

        /* accessor function helps to 
        get the root node in main function
        because root is private data member direct access is not possible */
        Node* getRoot() {
            return root;
        }

        /* mutator method helps to update root ptr after insertion
        root is not directly updatable in the main because its private data member */
        void setRoot(Node* ptr) {
            root = ptr; 
        }
};

/* Helper function to create a new node in each function call of insertNode */
Node* BinaryTree :: createNode(int n) {
    Node* newNode = new struct Node();
    newNode->data = n;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode; 
}

/* Helps to get inorder predessor to delete the node from tree */
Node* BinaryTree :: findMinimum(Node* rootPtr) {
    while(rootPtr->left != NULL) {
        rootPtr = rootPtr->left;
    }
    return rootPtr;
}

/* insertion of the Node */
Node* BinaryTree :: insertNode(Node* rootPtr, int n) {
    if(rootPtr == NULL) {
        return createNode(n);
    }
    if(n < rootPtr->data) {
        rootPtr->left = insertNode(rootPtr->left, n);
    }
    if(n > rootPtr->data) {
        rootPtr->right = insertNode(rootPtr->right, n);
    }
    return rootPtr;
}

/* function to delete the Node */
Node* BinaryTree :: deleteNode(Node* rootPtr, int n) {
    if(rootPtr == NULL) {
        cout<<"Node to be deleted is not present.!"<<endl;
        return rootPtr;
    }
    else if(n < rootPtr->data) {
        rootPtr->left = deleteNode(rootPtr->left, n);
    } else if(n > rootPtr->data) {
        rootPtr->right = deleteNode(rootPtr->right, n);
    } else {
        if(rootPtr->left == NULL && rootPtr->right == NULL) {
            delete rootPtr;
            rootPtr = NULL;
        }
        else if(root->left == NULL) {
            struct Node* temp = rootPtr;
            rootPtr = rootPtr->right;
            delete temp;
        }
        else if(rootPtr->right == NULL) {
            struct Node* temp = rootPtr;
            rootPtr = rootPtr->left;
            delete temp;
        } else {
            Node* temp = findMinimum(rootPtr->right);
            rootPtr->data = temp->data;
            rootPtr->left = deleteNode(rootPtr->right, temp->data);
        }
    }

    return rootPtr;
}

/* all traversal technique */
void BinaryTree :: inOrder(Node* root) {
    if(root == NULL) {
        return;
    }
    inOrder(root->left);
    cout<<root->data<<"\t";
    inOrder(root->right);
}

void BinaryTree :: preOrder(Node* root) {
    if(root == NULL) return;
    cout<<root->data<<"\t";
    preOrder(root->left);
    preOrder(root->right);
}

void BinaryTree :: postOrder(Node* root) {
    if(root == NULL) return;
    postOrder(root->left);
    postOrder(root->right);
    cout<<root->data<<"\t";
}

int main() {
    BinaryTree l1;
    int ch, ele, res;
    Node* ptr;
    do {
            cout<<"1 - Insert Node\n";
            cout<<"2 - IN-ORDER Traversal\n";
            cout<<"3 - PRE-ORDER Traversal\n";
            cout<<"4 - POST-ORDER Traversal\n";
            cout<<"Enter choice\n";
            cin>>ch;
            switch(ch) {
                case 1: 
                    cout<<"Entre element to insert to the List\n";
                    cin>>ele;
                    /* calling insertNode function by passing root ptr to the function, 
                       root ptr can be obtained by accessor function getRoot() */
                    ptr = l1.insertNode(l1.getRoot(), ele);
                    /* updating the root ptr*/
                    l1.setRoot(ptr);
                    break;
                case 2:
                    cout<<"---IN-ORDER TRAVERSAL---"<<endl;
                    l1.inOrder(l1.getRoot());
                    cout<<endl;
                    break;
                case 3:
                    cout<<"---PRE-ORDER TRAVERSAL---"<<endl;
                    l1.preOrder(l1.getRoot());
                    cout<<endl;
                    break;
                case 4:
                    cout<<"---POST-ORDER TRAVERSAL---"<<endl;
                    l1.postOrder(l1.getRoot());
                    cout<<endl;
                    break;
                case 5:
                    cout<<"Enter node to be deleted."<<endl;
                    cin>>ele;
                    ptr = l1.deleteNode(l1.getRoot(), ele);
                    l1.setRoot(ptr);
                default: cout<<"Invalid choice"<<endl;
            }
    } while(ch >=1 && ch <= 5);
    return 0;
}

答案 2 :(得分:0)

您的代码最大的问题是以下几行:

if (item < root -> data) {
        insert(item);
    }
    if (item > root -> data) {
        insert(item);
    }

基本上,您说的是,如果该项目大于或小于根数据,则将使用相同的项目再次调用该函数,而您从未更改过该项目,并且基本上可以无限制地执行此操作...。