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

c++ error LNK2019: binary search tree

本文关键字:搜索树 错误 LNK2019 c++      更新时间:2023-10-16

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

如果我#include .cpp文件:我的插入函数和正确构造树有一个问题。我正在观察我的局部变量和根的行为奇怪-在第一个值被添加根是指向没有数据的东西。(我对c++很陌生,所以请原谅我,这是我第一次创建模板类&二叉搜索树)

每次到达while(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;
}

在while循环条件中不应该是

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

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

你的算法有几个问题,我将指出其中的几个。

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

负责根不为空的条件。代码下面有

Node<Item> *p = root;

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

这里的一个错误已经指向另一个答案,但是p不可能是空的,因为在这一点p与根相同,p永远不会改变,所以你总是指向根。

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;
  }
}