简体   繁体   English

在没有节点指针作为参数的情况下遍历二进制搜索树

[英]In order traversal for binary search tree without node pointer as parameter

I have to code up a function for a lab in a binary search tree for in order traversal. 我必须在二进制搜索树中为实验室编写函数以便顺序遍历。 My problem is I've been given an interface that I have to follow and in it the only parameter I can pass to the traversal function is another function of void return type: 我的问题是,我已经得到一个必须遵循的接口,并且在其中可以传递给遍历函数的唯一参数是void返回类型的另一个函数:

void BinarySearchTree<ItemType, KeyType>::inorderTraverse(void visit(ItemType&)) const 

The visit function is basically a function that I would define for a specific use case for the tree, like say I want to print out the tree in ascending order in which case the function I would pass to the inorderTraverse function would be a print function. 访问函数基本上是我将为树的特定用例定义的函数,例如说我想按升序打印出树,在这种情况下,我将传递给inorderTraverse函数的函数将是打印函数。 I can't figure out how to traverse the entire tree without having a node pointer as a parameter. 我无法弄清楚如何在没有节点指针作为参数的情况下遍历整个树。 I'm not asking for the entire code, just advice that can point me in the right direction! 我并不是在索要完整的代码,只是可以为我指明正确方向的建议! Here's the BinarySearchTree.h : 这是BinarySearchTree.h

template<typename ItemType, typename KeyType>
class BinarySearchTree
{
private:
   BinaryNode<ItemType>* rootPtr;

   // Recursively deletes all nodes from the tree.
   void destroyTree(BinaryNode<ItemType>* subTreePtr);

   // Recursively finds where the given node should be placed and
   // inserts it in a leaf at that point.
   BinaryNode<ItemType>* insertInorder(BinaryNode<ItemType>* subTreePtr,
                                   BinaryNode<ItemType>* newNode);

   // Returns a pointer to the node containing the given value,
   // or nullptr if not found.
   BinaryNode<ItemType>* findNode(BinaryNode<ItemType>* treePtr,
                              const KeyType& target) const;

public:
   //------------------------------------------------------------
   // Constructor and Destructor Section.
   //------------------------------------------------------------
   BinarySearchTree();
   virtual ~BinarySearchTree();

   //------------------------------------------------------------
   // Public Methods Section.
   //------------------------------------------------------------
   bool add(const ItemType& newEntry);
   ItemType getEntry(const KeyType& aKey) const throw(NotFoundException);
   bool contains(const KeyType& aKey) const;

   //------------------------------------------------------------
   // Public Traversals Section.
   //------------------------------------------------------------
   void inorderTraverse(void visit(ItemType&)) const;
}; // end BinarySearchTree

#include "BinarySearchTree.cpp"

#endif

I'm assuming the BinaryNode has the methods 我假设BinaryNode具有方法

const BinaryNode* getLeft() const;
const BinaryNode* getRight() const;
const ItemType& getValue() const;

[Edited due to: "got told that we couldn't add anything extra to the class"] [由于以下原因而被编辑:“请注意,我们无法在课程中添加任何其他内容”]

You see, that method is static - it means it doesn't rely on any knowledge about the particular instant of your tree. 您会看到,该方法是static -这意味着它不依赖于有关树的特定瞬间的任何知识。

Because of this, it can be placed anywhere. 因此,它可以放置在任何地方。

For example, just write it as a static function outside the class, inside your "BinarySearchTree.cpp" file. 例如,只需将其作为静态函数写入类的"BinarySearchTree.cpp"文件内即可。

Another solution: implement it inside the inorderTraverse method, as a lambda function like in: 另一个解决方案:inorderTraverse方法中实现它,作为lambda函数,如下所示:

  // as a method of this class, you **do** have access to the root node
  void inorderTraverse(void visit(const ItemType&)) const {
    // this is a lambda function
    auto inOrderRecurse=(
      const BinaryNode<ItemType>* node, 
      void visit(const ItemType&)
    ) {
         if(node) {
           auto n=node->getLeft();
           if(n) {
              this->inOrderRecurse(n, visit);
           }
           visit(node->getValue());
           n=node->getRight();
           if(n) {
             this->inOrderRecurse(n, visit);
           }
        }
      }
    ;
    inOrderRecurse(this->rootPtr);
  }

Yet another solution : if you aren't allowed to use lambdas, you can still declare a class/structure inside you method . 还有另一种解决方案 :如果不允许使用lambda,则仍可以在method内部声明一个类/结构 So, let's declare/use one in the very inorderTraverse method. 因此,让我们在inorderTraverse方法中声明/使用一个。

  // as a method of this class, you **do** have access to the root node
  void inorderTraverse(void visit(const ItemType&)) const {
    struct recurser {
      static void inOrderRecurse(
        const BinaryNode<ItemType>* node, 
        void visit(const ItemType&)
      ) {
       // etc...
      }
    };
    recurser::inOrderRecurse(this->rootPtr);
  }

[original answer] [原始答案]

As such, the inorderTraverse can be implemented as: 这样,可以将inorderTraverse实现为:

private:
  // "All problems in computer science can be solved by another level of indirection, 
  // except of course for the problem of too many indirections."
  // In the context, **this method** is another level of indirection
  static void inOrderRecurse(
      const BinaryNode<ItemType>* node, 
      void visit(const ItemType&)
  ) const {
   if(node) {
     auto n=node->getLeft();
     if(n) {
       this->inOrderRecurse(n, visit);
     }
     visit(node->getValue());
     n=node->getRight();
     if(n) {
       this->inOrderRecurse(n, visit);
     }
  }
public:

  // as a method of this class, you **do** have access to the root node
  void inorderTraverse(void visit(const ItemType&)) const {
    // note this `const` here  ---^ needed because of ^^^^ this one
    inOrderRecurse(this->rootPtr);
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM