为什么代码创建错误的二进制搜索树

时间:2015-12-29 16:09:12

标签: c++ algorithm data-structures binary-tree binary-search-tree

我正在尝试创建一个二进制搜索树sicne早上,我仍然无法做到,   当我看到调试时形成的树然后它不正确时,输出错误。

我怎么做?

       // BinaryTree.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <array>
using namespace std;

struct Tree
{
    Tree*left = NULL;
    Tree*right = NULL;
    int data;

};
int counte = 0;
int values[] = { 8, 5, 4, 9, 7, 11, 1, 12, 3, 2 };
int val = values[counte];
Tree*storeRoot = NULL;
int _tmain(int argc, _TCHAR* argv[])
{
    Tree *tree = NULL;
    void CreateBinarySearchTree(Tree**RootOfTree, int* values, int size);

    int size = sizeof(values) / sizeof(values[1]);
    Tree* RootOfTree = NULL;
    if (tree == NULL)
    {
        tree = new Tree();
        RootOfTree = tree;
        tree->data = values[0];
        tree->left = NULL;
        tree->right = NULL;
    }
    storeRoot = RootOfTree;
    CreateBinarySearchTree(&RootOfTree, values, size);
    return 0;
}

void CreateBinarySearchTree(Tree**RootOfTree, int* values, int size)
{

    Tree *tree = NULL;
    if (counte > size)
    {
        return;
    }

    if ((*RootOfTree)->left == NULL && (*RootOfTree)->right == NULL)
    {
        counte++;
        val = values[counte];
        tree = new Tree();
        tree->data = val;
        tree->left = NULL;
        tree->right = NULL;
        if ((*RootOfTree)->data < val)
        {
            (*RootOfTree)->right = tree;
        }
        else if ((*RootOfTree)->data > val)
        {
            (*RootOfTree)->left = tree;
        }
        CreateBinarySearchTree(&(*RootOfTree), values, size);
    }
    else if ((*RootOfTree)->left == NULL && (*RootOfTree)->right != NULL)
    {
        counte++;
        val = values[counte];
        if ((*RootOfTree)->data > val)
        {
            tree = new Tree();
            tree->data = val;
            tree->left = NULL;
            tree->right = NULL;
            (*RootOfTree)->left = tree;
        }
        else
        {
            counte--;
            CreateBinarySearchTree(&(*RootOfTree)->right, values, size);
        }
    }
    else if ((*RootOfTree)->left != NULL && (*RootOfTree)->right == NULL)
    {
        counte++;
        val = values[counte];
        if ((*RootOfTree)->data < val)
        {
            if (storeRoot->data > val)
            {
                tree = new Tree();
                tree->data = val;
                tree->left = NULL;
                tree->right = NULL;
                (*RootOfTree)->right = tree;
            }
            else
            {
                if (storeRoot->right == NULL)
                {
                    tree = new Tree();
                    tree->data = val;
                    tree->left = NULL;
                    tree->right = NULL;
                    (storeRoot)->right = tree;
                }
                else
                {
                    counte--;
                    CreateBinarySearchTree(&storeRoot, values, size);
                }
            }
        }
        else
        {
            counte--;
            CreateBinarySearchTree(&(*RootOfTree)->left, values, size);
        }
    }
}

我的完整代码在这里:

format()

请在任何我错的地方纠正我,这样它就会创建二元海草树。 请在回答时提供详细说明,谢谢

1 个答案:

答案 0 :(得分:2)

让我们从顶部开始。什么是二叉搜索树(BST)?二叉搜索树是一种数据结构,其中给定节点左侧的每个节点都包含一个小于的值,并且给定节点右侧的每个节点都包含一个值更大

看看你的代码。您认为树的根是树本身(树的根是Tree类型)。这是不正确的;树的根是一个节点。每个节点都存储一个值,以及指向其他节点的两个指针:左边和右边的子节点。让我们把它翻译成代码:

class BST {

public:
    BST() : head(nullptr) {}
    ~BST() { /* Implement */ }
    void insert(int value);
private:
    struct Node{
        Node(int d, Node *l = nullptr, Node *r = nullptr) : data(d), left(l), right(r) {} 
        int data;
        Node *left, *right;
    } *head;
    void insert(Node *n, int val);
};

现在,在您的插入算法上。您的创建函数应该处理创建树的所有细节。也就是说,您的用户实际上不应该负责创建树并将其传入。这与您的函数名称相矛盾。此外,您的函数创建了太多可以轻松推广的子类。我们想检查三件事:

  1. 树是否为空(例如是指向nullptr的根)?
  2. 如果是,请填写根并返回。
  3. 否则,请检查插入值并递归树,直到找到值的合适位置。
  4. 您可以使用我们的新OOP设计轻松实现此功能,并将实际插入委派给私有成员函数。我们这样做的原因是因为我们只想在我们改变它所指向的内容时修改头指针(当树是空的并且我们填充它或者我们正在破坏树时)。在所有其他情况下,我们希望头指针只是插入函数的起点。将我们的插入委托给将头部作为指针的私有插入函数将复制头指针,因此不会修改原始指针:

    void BST::insert(int value) 
    {
        insert(head, value);
    }
    
    void BST::insert(Node *n, int val)
    {
        if (!head) {
            head = new Node(val);
            return;
        }
    
        if (val < n->data) {
            if (n->left)
                insert(n->left, val);
            else
                n->left = new Node(val);
        } else if (val > n->data) {
            if (n->right)
                insert(n->right, val);
            else
                n->right = new Node(val);
        }
    }