模板化二叉搜索树c ++,未解决的外部错误

时间:2013-05-12 05:30:59

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

我正在处理二叉搜索树的模板,我收到以下错误。我知道有类似的帖子,但我无法弄清楚这件事。模板对我来说绝对是一个弱小的主题所以我认为我缺少一些基本的语义,但我可以把它放在它上面。以下是错误,而不是之后的程序文件。如果有人能指出我正确的方向,我会非常感激。

  

错误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 \二叉树\ main.obj

- 主要用于测试

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

using namespace std;

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

    return 0;
}

-tree template

#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

2 个答案:

答案 0 :(得分:2)

嘿。问题是您忘记了insertHelper函数名前面的作用域限定符 Tree&lt; ItemType&gt; ::

这样做:

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

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

答案 1 :(得分:1)

下面:

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

    return true;
}

如果rootPtr为NULL,则rootPtr->data无效。

也许你的意思是:

if(rootPtr == NULL)
{
    rootPtr = new TreeNode<ItemType>(newItem);
}