c ++错误LNK2019:二叉搜索树

时间:2015-10-25 16:51:05

标签: c++ templates binary-tree linker-errors lnk2019

认为我的根声明存在问题,我的插入函数,默认构造函数和析构函数中出现了三个错误。

如果我#include .cpp文件: 我的插入函数存在问题并正确构造树。我正在观察我的局部变量和root表现得很奇怪 - 在添加第一个值之后,root指向没有数据的东西。 (我对C ++很陌生,所以请耐心等待,这是我第一次创建模板类和二进制搜索树)

每次到达该行时都会抛出异常(p-> data!= item)。

这是我的插入功能:

    template <class Item>
void Tree<Item>::insert(Item item)
{
    Node<Item> *new_node = new Node<Item>();
    new_node->data = item;

    if (root == nullptr)
    {
        root = new_node;
    }
    else
    {
        Node<Item> *q = nullptr;
        Node<Item> *p = root;
        while (p != nullptr && q->data != item)
        {
            q = p;
            if (item < p->data)
            {
                q = p->lchild;
            }
            else if (item > p->data)
            {
                q = p->rchild;
            }
        }
        if (q->data == item)
        {
            cout << "Duplicate Data" << endl;
        }
        else
        {
            if (item > q->data)
            {
                q->rchild = new_node;
            }
            else
            {
                q->lchild = new_node;
            }
        }
    }
}

部首:

#pragma once
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

template <class Item>
struct Node
{
    //Default constructor for Node
    //Purpose: Initialize all values
    //Parameters: None
    //Returns: None
    Node();

    //Parameterized constructor for Node
    //Purpose: Initialize all values
    //Parameters: a data Item, and Node pointers for left and right children
    //Returns: None
    Node(Item, Node<Item>*, Node<Item>*);

    //variables
    Item data;
    Node<Item> *lchild;
    Node<Item> *rchild;
};

template <class Item>
class Tree
{

public:
    //Default constructor for Tree
    //Purpose: Initialize all values
    //Parameters: None
    //Returns: None
    Tree();

    //Copy constructor
    //Purpose: create new Tree
    //Parameters: A Tree object
    //Returns: Tree
    Tree(const Tree&);

    //copy
    //Purpose: To copy values
    //Parameters: Node pointer
    //Returns: None
    void copy(Node<Item>*);

    //chop
    //Purpose: Delete tree
    //Parameters: Node pointer
    //Returns: None
    void chop(Node<Item>*);

    //Destructor
    //Purpose: Clean up data, delete tree
    //Parameters: None
    //Returns: None
    ~Tree();

    //operator=
    //Purpose: Overload assignment operator
    //Parameters: a const ref to a Tree object
    //Returns: Tree
    const Tree<Item>&operator=(const Tree&);

    //insert
    //Purpose: To add a value to tree
    //Parameters: A const reference to an Item
    //Returns: None
    void insert(Item);

    //inOrderTraverse
    //Purpose: To traverse the tree in order
    //Parameters: A Node pointer
    //Returns: None
    //void inOrderTraverse(Item);


private:
    Node<Item> *root;
};

这是我的Tree类:

   #include "Tree.h"

template <class Item>
Node<Item>::Node()
{
    data = 0;
    lchild = nullptr;
    rchild = nullptr;
}

template <class Item>
Node<Item>::Node(Item _data, Node<Item> *_lchild, Node<Item> *_rchild)
{
    data = _data;
    lchild = _lchild;
    rchild = _rchild;
}

template <class Item>
Tree<Item>::Tree()
{
    root = nullptr;
}

template <class Item>
void Tree<Item>::copy(Node<Item> *c)
{
    if (c)
    {
        insert(c->data);
        copy(c->lchild);
        copy(c->rchild);
    }
}

template <class Item>
void Tree<Item>::chop(Node<Item> *c)
{
    if (c)
    {
        chop(c->lchild);
        chop(c->rchild);
        delete c;
    }
}

template <class Item>
Tree<Item>::Tree(const Tree& t)
{
    root = nullptr;
    copy(t.root);
}

template <class Item>
Tree<Item>::~Tree()
{
    chop(root);
}

template <class Item>
const Tree<Item>&Tree<Item>::operator=(const Tree& t)
{
    if (this != &t)
    {
        chop(root);
        root = nullptr;
        copy(t.root);
    }
    return *this;
}

template <class Item>
void Tree<Item>::insert(Item item)
{
    Node<Item> *new_node = new Node<Item>();
    new_node->data = item;

    if (root == nullptr)
    {
        root = new_node;
    }
    else
    {
        Node<Item> *p = root;
        Node<Item> *q = nullptr;
        while (p->data != item)
        {
            q = p;
            if (item < p->data)
            {
                p = p->lchild;
            }
            else if (item > p->data)
            {
                p = p->rchild;
            }
        }
        if (p-> data == item)
        {
            cout << "Duplicate Data" << endl;
        }
        else 
        {
            if (item < q->data)
            {
                q->lchild = new_node;
            }
            else
            {
                q->rchild = new_node;
            }
        }

    }
}

主:

#include "Tree.h"

int main()
{
    //variables for data
    string file;
    ifstream infile(file);
    Tree<int> myTree;
    int d = 0;

    //ask user to enter filename
    cout << "Please enter the file you wish to open: " << endl;
    getline(cin, file);
    infile.open(file.c_str());

    //make sure filename is valid
    while (!infile)
    {
        cout << "Error opening file, please enter the name of the file you wish to open: " << endl;
        getline(cin, file);
        infile.open(file.c_str());
    }

    //if file is good, build tree
    while (!infile.eof())
    {
        myTree.insert(d);
        infile >> d;
        cout << d << endl;
    }

    system("PAUSE");
    return 0;
}

2 个答案:

答案 0 :(得分:2)

您的算法存在一些问题,我将指出其中几个问题。

if (root == nullptr)
{
    root = new_node;
}

负责root不为null的条件。记下您的代码

Node<Item> *p = root;

while (p != nullptr && p->data != item)

此处的一个错误已在另一个答案中指出,但p不能为空,因为此时p与root相同而p永远不会改变,所以你经常指向root。

q = p // I would do q = root;

应该在循环之外。循环内部应该是这样的:

while(q != nullptr) {
  if(newNode->data < q->data) {
    q = q->leftChild;
  } else if(newNode->data > q->data) {
    q = q->rightChild;
  } else {
    cout << "ERROR: item already exists";
    return 1;
  }
}

答案 1 :(得分:1)

在while循环条件中不应该是

while (p != nullptr && p->data != item)

q只是一个空指针,[q-&gt; data!= item]将永远为真。