0

我正在研究二叉搜索树的模板,但出现以下错误。我知道有类似的帖子,但我无法弄清楚这件事。模板对我来说绝对是一个薄弱的主题,所以我认为我遗漏了一些基本的语义内容,但我可以把手指放在上面。下面是错误,之后是程序文件。如果有人能指出我正确的方向,我将不胜感激。

错误 1 ​​错误 LNK2019:引用了未解析的外部符号“private: bool __thiscall Tree::insertHelper(class TreeNode * &,int)”(?insertHelper@?$Tree@H@@AAE_NAAPAV?$TreeNode@H@@H@Z)在函数 "public: bool __thiscall Tree::insert(int)" (?insert@?$Tree@H@@QAE_NH@Z) C:\Users\wm\documents\visual studio 2012\Projects\binaryTree\binaryTree\main .obj

- 用于测试的基本主程序

#include "BinarySearchTree.h"
#include "TreeNode.h"
#include <iostream>

using namespace std;

int main()
{
    Tree<int> test;
    test.insert(55);

    return 0;
}

-树模板

#include <iostream>
#include "TreeNode.h"

using namespace std;

template< class ItemType >
class Tree {
public:

   Tree(); 
   ~Tree();     
   bool isEmpty() const;
   void makeEmpty();
   bool insert( ItemType newItem);
   bool retrieve( ItemType searchItem, ItemType & foundItem );
   bool deleteItem (ItemType deleteItem);
   void print();

private:

   TreeNode< ItemType > * rootPtr;  // pointer to the root

   //utility functions 
   void printHelper( TreeNode< ItemType > * );
   bool insertHelper(TreeNode< ItemType > * & node, ItemType item);
   bool deleteHelper( TreeNode< ItemType > * & , ItemType );
   void deleteNode( TreeNode<ItemType > * & );
   bool retrieveHelper( ItemType, TreeNode< ItemType > * & , ItemType & );

};

template<class ItemType>
Tree<ItemType>::Tree()
{
    rootPtr = NULL;
}
template<class ItemType>
Tree<ItemType>::~Tree()
{
    makeEmpty();
}
template<class ItemType>
bool Tree<ItemType>::isEmpty() const
//Returns True if the tree is empty, otherwise returns false
//Postcondition: Tree is unchanged.
{
    if(rootPtr == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }
}
template<class ItemType>
void Tree<ItemType>::makeEmpty()
 //Makes the tree empty if it is not empty already.
 //Preconditions:  The tree exists.
//Postconditions: Tree is now empty. Any dynamically allocated memory which is no longer used is returned to the system. 
{
    return;
}
template<class ItemType>
bool Tree<ItemType>::insert( ItemType newItem)
// Inserts a copy of newItem in the tree.
//Precondition: The tree exists and has binary search property.
//Postcondition: if the tree already has an item where item == newItem, the function returns false and the trre is unchanged.
//Otherwise, the newItem is inserted in the tree preserving and the binary search property is maintained.
{
    if(rootPtr == NULL)
    {
        rootPtr->data = newItem;

        return true;
    }
    else
    {
        return insertHelper(rootPtr, newItem);
    }
}
template<class ItemType>
bool insertHelper( TreeNode< ItemType > * & node, ItemType item)
{
    if( item < node->data)//left
    {
        if(node->leftPtr == NULL)
        {
            node->leftPtr = new TreeNode<ItemType>(item);
            return true;
        }
        else
        {
            return insertHelper(node->leftPtr,item);
        }
    }
    else if(node->data < item)//right
    {
        if(node->righChild == NULL)
        {
            node->rightPtr = new TreeNode<ItemType>(item);
            return true;
        }
        else
        {
            return insertHelper(node->rightPtr,item);
        }
    }
    else// same value
    {
        return false;
    }
}
template<class ItemType>
bool Tree<ItemType>::retrieve( ItemType searchItem, ItemType & foundItem )
// Given a searchItem, it tries to retrieve as foundItem, an item in the tree where the item == searchItem. 
// Precondition:The tree exists and has the binary search property.
// Postcondition: If the tree already has an item where item == searchItem, foundItem is set to that item, and the function returns true.
//   If the tree has no such item, the function returns false and foundItem remains unchanged.  The tree is unchanged.
{

}
template<class ItemType>
bool Tree<ItemType>::deleteItem (ItemType deleteItem)
// Given a deleteItem, it deltes from the tree any item where item == deleteItem.
// Precondition: Tree exists and has binary search property.
// Postcondition: If the tree has an item where item == deleteItem, that item is removed from the tree, and the function returns true, and
// the binary search property is maintained. If the tree has no such item, the function returns false and the tree remains unchanged.
{

}
template<class ItemType>
void Tree<ItemType>::print()
// Prints the items in the tree in ascending order to the screen
// Precondition: The tree exists and has binary search property.
// Postcondition: The items have been printed in ascending order and the tree is unchanged
{

}
template<class ItemType>
void printHelper( TreeNode< ItemType > * )
{

}
template<class ItemType>
bool deleteHelper( TreeNode< ItemType > * & , ItemType )
{

}
template<class ItemType>
void deleteNode( TreeNode<ItemType > * & )
{

}
template<class ItemType>
bool retrieveHelper( ItemType, TreeNode< ItemType > * & , ItemType & )
{

}

-treenode

#ifndef TREENODE_H
#define TREENODE_H

template< class ItemType > class Tree;  // forward declarations

template<class ItemType>
class TreeNode {
   friend class Tree< ItemType >; // make Tree a friend

public:
   TreeNode( ItemType );  // constructor
   TreeNode();                  // constructor with data uninitialized 
   ItemType getData() const;      // return data in the node
private:
   ItemType data;                 
   TreeNode< ItemType > *leftPtr; 
   TreeNode< ItemType > *rightPtr;
};

// Constructor
template<class ItemType>
TreeNode< ItemType >::TreeNode( ItemType newItem )
{ 
    data = newItem;
    leftPtr = NULL;
    rightPtr = NULL;
}

template<class ItemType>
TreeNode< ItemType >::TreeNode( )
{ 
    leftPtr = NULL;
    rightPtr = NULL;
}


// Return a copy of the data in the node
template< class ItemType >
ItemType TreeNode< ItemType >::getData() const 
{ 
    return data; 
}

#endif
4

2 回答 2

2

呵呵。问题是您忘记了insertHelper 的函数名称前面的作用域限定符Tree<ItemType>:: 。

只需这样做:

template<class ItemType>
bool Tree<ItemType>::insertHelper( TreeNode< ItemType > * & node, ItemType item)

顺便说一句,链接器错误应该向您表明这是问题所在。首先,你知道你有一个链接问题,而不是编译问题。其次,您知道找不到的符号是* Tree<ItemType>:: *insertHelper(...)。第三,您知道对该函数的调用已在 Tree<ItemType>::insert 中成功编译,这意味着编译器找到并解析了 insertHelper 方法的声明,没有问题。链接器无法找到该方法的实际目标代码的唯一可能解释是该函数的定义不存在或与您声明的名称不同!

于 2013-05-12T05:54:53.420 回答
1

这里:

if(rootPtr == NULL)
{
    rootPtr->data = newItem;

    return true;
}

如果 rootPtr 是NULLrootPtr->data无效。

也许你的意思是:

if(rootPtr == NULL)
{
    rootPtr = new TreeNode<ItemType>(newItem);
}
于 2013-05-12T05:51:57.070 回答