1

我正在做作业,我正在尝试实现一些二叉搜索树功能。我对编程也很陌生,对编程没有太多经验。我已经写出了函数,但我想弄清楚我收到的错误。我收到的错误是btree.h(76): error C2664: 'Node<T>::find_node' : cannot convert parameter 1 from 'Node<T> *' to 'const int &' with [ T=int ] Reason: cannot convert from 'Node<T> *' to 'const int' with [ T=int ]

这就是为什么我也放 cpp 文件的原因。在 cpp 文件中也会出现错误。所有文件均由我的教授提供。我只需要向 node.h 添加 2 个方法,就是这样。这是cpp文件tree2.cpp中的错误

tree2.cpp(28) : see reference to class template instantiation 'BinaryTree<elemType>' being compiled with [ elemType=int ]

如果有人可以帮助解释如何通过建议解决错误,那就太好了。

btree.h

#include    <iostream>
#include    "node.h"
//using namespace std;

template < typename elemType >
class BinaryTree {
  public:
BinaryTree( );
~BinaryTree( );
void insert( const elemType & );
void remove( const elemType & );
void inorder( );
bool empty( );
void clear( );

private:
Node< elemType >    *_root;

BinaryTree( const BinaryTree & );
BinaryTree &operator =( const BinaryTree & );
void clear( Node< elemType > * );
};

template < typename elemType >
inline BinaryTree< elemType >::BinaryTree( ) : _root(0)
{
    cout << "BinaryTree::BinaryTree() "
       << "default constructor\n";
}

template < typename elemType >
inline BinaryTree< elemType >::~BinaryTree( )
{
   cout << "BinaryTree::~BinaryTree() destructor\n";
   clear( );
}

template < typename elemType >
inline void BinaryTree< elemType >::clear( )
{
   if( _root )
   {
      clear( _root );
      _root = 0;
   }
}

template < typename elemType >
inline void BinaryTree< elemType >::clear( Node< elemType > *pt )
{
   if( pt ) {
      cout << "clear( ) left of  "  << pt->value( ) << '\n';
      clear( pt->left( ) );
      cout << "clear( ) right of " << pt->value( ) << '\n';
      clear( pt->right( ) );
      delete pt;
    }
}

template < typename elemType >
inline void BinaryTree< elemType >::insert( const elemType &e )
{
   if( !_root )
   {
      _root = new Node< elemType >( e );
   }
   else
   {
      _root->insert_value( e );
   }
}

template < typename elemType >
inline void BinaryTree< elemType >::remove( const elemType &e )
{
  _root->find_node( _root, e );
}

template < typename elemType>
inline void BinaryTree< elemType >::inorder( )
{
   _root->inorder( _root );
   cout << '\n';
}

node.h

#ifndef     NODE_H

#define     NODE_H

#include    <string>

using namespace std;

template< typename T >
class Node
{
  public:
      Node( const T &);

      T  value( )  const;
      T  value( const T & );

      void insert_value( const T & );
      void inorder( const Node * );
      void find_node( const T &val, const T* root );
    //bool find_node( const T &val, Node < T > *node) const;
      void delete_node( Node< T > *&p );

      Node *  left ( ) const;
      Node *  left ( Node * );
      Node *  right( ) const;
      Node *  right( Node * );

   private:
      T       _value;
      Node *  _left;
      Node *  _right;
      Node< T > * root; //point to root node
      Node::Node( const Node & );
      Node &operator =( const Node & );



};


template< typename T >
inline Node< T >::Node( const T &rhs )
{
   _value = rhs;                       // assign rhs to _value
   _left  =  _right = 0;               // node is not part of a tree yet
}


template< typename T >
inline T Node< T >::value( ) const
{
   return _value;
}


template< typename T >
inline T Node< T >::value( const T &rhs )
{
   _value = rhs;                       // new value for _value
   return _value;
}


template< typename T >
inline Node< T > *Node< T >::left( ) const
{
   return _left;
}


template< typename T >
inline Node< T > *Node< T >::left( Node< T > *rhs )
{
   _left = rhs;

   return _left;
}


template< typename T >
inline Node< T > *Node< T >::right( ) const
{
   return _right;
}


template< typename T >
inline Node< T > *Node< T >::right( Node< T > *rhs )
{
   _right = rhs;
   return _right;
}


template< typename T >
inline void Node< T >::insert_value( const T &val )
{
    if( val == _value )
{
    return;                     // value already in the tree
}
if( val < _value )              // val should appear at the left
{
    if( ! _left )               // no left subtree ?
    {                           // add new node here
        _left = new Node( val );
    }
    else                        // try the subtree
    {
        _left->insert_value( val );
    }
}
else                            // val should appear at the right
{
    if( ! _right )              // no right subtree ?
    {                           // add new node here
        _right = new Node( val );
    }
    else                        // try the subtree
    {
        _right->insert_value( val );
    }
  }
}


template< typename T >
inline void Node< T >::inorder( const Node< T > *pt )
{
   if( pt )
   {
      inorder( pt->_left );
      cout << std::hex << pt->_left << std::dec << '\t';
      cout << std::hex << pt << std::dec << '\t';
      cout << std::hex << pt->_right << std::dec << '\t';
      cout << pt->_value << '\n';
      inorder( pt->_right );
   }
}


template <typename T>
Node<T> const * find_node(const T &val)
{
   Node<T> const * curr = root;
   while( curr != 0 )
   {
      if (val == curr -> _value)  {
       break;
    }
    else if (val < curr -> _value) {
        curr = curr -> _left;
    |
    else {
        curr = curr -> _right;
    }
}
return curr;
}
}

template <typename T >
inline void find_node( const T & val, const T * root ) {
Node<T> const * ptrFoundNode = find_node_pointer( val, root );
if( ptrFoundNode ) {
    delete_node( ptrFoundNode, root );
  }
}

template< typename T >
inline void Node< T >::delete_node(Node < T > *&p)
{

Node<T> *curr, *prev, *temp;
   if (p == NULL) return;
   if (p->_left == NULL && p->_right == NULL) {
    // no children - easy
    // *** if allowing counted duplicates:
    // ***    if (p->getCount() > 1) (*p)--;
    // ***    else {
       temp = p;
       p = NULL;
       delete temp;
    }
 else if (p->_left == NULL) {
    // only a right child - still easy
    // *** if allowing counted duplicates:
    // ***    if (p->getCount() > 1) (*p)--;
    // ***    else {
       temp = p;
       p = temp->_right;
       delete temp;
    }
 else if (p->_right == NULL) {
    // only a left child - still easy
    // *** if allowing counted duplicates:
    // ***    if (p->getCount() > 1) (*p)--;
    // ***    else {
       temp = p;
       p = temp->_left;
       delete temp;
    }
 else {
    // two children - this is the hard case
    // use successor: once right, then as far left as possible
    // *** if allowing counted duplicates:
    // ***    if (p->getCount() > 1) (*p)--;
    // ***    else {
       curr = p->_right;
       prev = NULL;
       while (curr->_left != NULL) {
           prev = curr;
           curr = curr->left;
       }
       p->data = curr->data;
       if (prev == NULL) p->_right = curr->_right;
       else prev->_left = curr->_right;

       delete curr;
   }
}


#endif

tree2.cpp

#include    "btree.h"
#include    <fstream>
#include    <string>

using namespace std;


ifstream get_ifs( )                             // get input file stream
{
   string filename;                            // input file name

   cerr << "name of file to read from? ";
   cin  >> filename;

   ifstream ifs( filename, ifstream::in );
   if( ! ifs )                                 // cannot open file infilen
   {
      cerr << "cannot open input file '" << filename << "'\n";
      exit( 1 );
   }

   return ifs;                                 // return input file stream
}


int main()
{
   BinaryTree< int > bt;

   bt.insert( 30 );
   bt.insert( 20 );
   bt.insert( 40 );
   bt.insert( 50 );
   bt.insert( 10 );
   bt.insert( 15 );
   bt.insert( 35 );

   cout << "inorder traversal:\n";
   bt.inorder( );

   ifstream ifs = get_ifs( );

   string cmd;
   int    value;

   while( ifs >> cmd )
   {
      ifs >> value;

      cout << cmd << '\t' << value << '\n';

      if( cmd == "a" )
      {
          bt.insert( value );
      }
      else if( cmd == "d" )
      {
          bt.remove( value );
       }
      else
      {
          cout << "invalid command '" << cmd << "' ignored...\n\n";
      }

      bt.inorder( );
      cout << '\n';
   }

   return 0;
}

tree1.cpp

#include    "btree.h"
#include    <fstream>
#include    <string>

using namespace std;


ifstream get_ifs( )                             // get input file stream
{
   string filename;                            // input file name

   cerr << "name of file to read from? ";
   cin  >> filename;

   ifstream ifs( filename, ifstream::in );
   if( ! ifs )                                 // cannot open file infilen
   {
      cerr << "cannot open input file '" << filename << "'\n";
      exit( 1 );
   }

   return ifs;                                 // return input file stream
}


int main()
{
   BinaryTree< string > bt;

   bt.insert( "Florida" );
   bt.insert( "California" );
   bt.insert( "Alabama" );
   bt.insert( "Mississippi" );
   bt.insert( "Georgia" );
   bt.insert( "Colorado" );
   bt.insert( "Idaho" );
   bt.insert( "Missouri" );
   bt.insert( "New York" );

   cout << "inorder traversal:\n";
   bt.inorder( );

   ifstream ifs = get_ifs( );

   string cmd, value;
   while( ifs >> cmd )
   {
      ifs >> value;

      cout << cmd << '\t' << value << '\n';

      if( cmd == "a" )
      {
          bt.insert( value );
      }
      else if( cmd == "d" )
      {
          bt.remove( value );
      }
      else
      {
          cout << "invalid command '" << cmd << "' ignored...\n\n";
      }

      bt.inorder( );
      cout << '\n';
   }

   return 0;
}
4

2 回答 2

0

是否更改以下行

inline void find_node(  const T & val, const T * root ) {

inline void find_node( const T * root, const T & val ) {

帮助?

另请参阅:修改二分搜索以查找然后删除

于 2013-04-04T00:26:54.313 回答
0

find_node方法希望T类型不是节点;它想要节点中的数据类型。

当它不想要它时,你正在将整个节点传递给它。

于 2013-04-04T00:38:40.330 回答