【问题标题】:Searching an unordered binary tree by key value按键值搜索无序二叉树
【发布时间】:2018-02-02 18:56:00
【问题描述】:

我之前发布了一个与此主题相关的问题,但我也无法弄清楚这一点。我正在尝试通过键值搜索无序二叉树并通过递归函数返回其关联值。

该类具有以下形式:

  Class Node
  {
     private:
       Node *leftChild;
       Node *rightChild;
       int key;
       int value;
 }

每个变量都有相关的 get 方法。所以我基本上想搜索二叉树并在到达正确的节点后返回它的值。

这是我迄今为止的尝试,我想我已经很接近了:

int preOrder(Node *node, int key)
{
   if(node->getKey() == key)
     return node->getValue();

  Node* leftNode = node->getLeft();

  if(leftNode != NULL)
  {
    return preOrder(leftNode, key);
  }

  Node* rightNode = node->getRight();

  if(rightNode != NULL)
  {
    return preOrder(rightNode, key);
  }

  //I know a return statement needs to be placed here
  //in case both pointers are NULL in order to return to the previous
  //node in the tree, but I'm not sure how to do this...
}

有人有什么建议吗?

【问题讨论】:

  • 等一下,我会挖掘出我在你上一个问题上写的课程。
  • 一条建议:使用有序树!

标签: c++ tree binary-tree


【解决方案1】:

给你。这包括回答您最后一个问题的代码,已修改为支持键/值节点而不仅仅是值节点。此外,通过这些更改,返回指向节点的指针而不是它包含的值是有意义的,所以我更新了最低以这样做。

template <typename KeyT, typename ValueT>
class Node
{
public:
    Node(KeyT k, ValueT v)
    {
        key = k;
        value = v;
        right = NULL;
        left = NULL;
    }

    Node<KeyT, ValueT> * lowest()
    {
        Node<KeyT, ValueT> * v = this;

        if (right != NULL)
            if (v->value > left->value) v = left;
        if (left  != NULL)
            if (v->value > right->value) v = right;

        return v;
    }

    Node<KeyT, ValueT> * searchByKey(KeyT k)
    {
        if (key == k)
            return this;

        Node<KeyT, ValueT> * n = NULL;

        if (left != NULL)
            n = left->searchByKey(k);
        if (n != NULL) return n;
        if (right!= NULL)
            n = right->searchByKey(k);
        if (n != NULL) return n;

        return NULL;
    }

    Node<KeyT, ValueT> * getRight()
    {
        return right;
    }

    Node<KeyT, ValueT> * getLeft()
    {
        return left;
    }

    void setRight(Node<KeyT, ValueT> * nright)
    {
        right = nright;
    }

    void setLeft(Node<KeyT, ValueT> * nleft)
    {
        left = nleft;
    }

    KeyT getKey()
    {
        return key;
    }

    ValueT getValue()
    {
        return value;
    }

private:
    KeyT   key;
    ValueT value;

    Node<KeyT, ValueT> * right;
    Node<KeyT, ValueT> * left;
};

查看示例输出:http://ideone.com/l5ZNc

【讨论】:

  • 哇是的,这对我来说非常适合。非常感谢您花时间来做这件事。泛化到 Node 类型时更容易处理
【解决方案2】:

是的,你很接近。当你没有找到钥匙时,你需要弄清楚要返回什么,因为这就是阻止你完成的原因。请注意,如果左节点不为 NULL,您将永远不会检查右节点。

【讨论】:

  • 是的,这就是 preOrder 遍历的工作原理——它从根开始,然后在扫描右子树之前遍历左子树。因此,在我完成对左侧的扫描之前,确实不会访问右侧子树。这是我卡住的地方,因为一旦两个子指针都为空,我就无法回溯到前一个节点。
  • @WakkaWakkaWakka,再看看你原来的代码。一旦你从左边走,你将永远到右边。
【解决方案3】:
    int value=NULL;
    void preOrder(Node *node, int key)
    {
       if (node!=NULL){
          if(node->getKey() == key)
            value=node->getValue();

          preOrder(node->getLeft(),key);
          preOrder(node->getRight(),key); 
       }     
    }

【讨论】:

  • 在这种情况下,break 到底是什么意思?
  • 对不起..我的印象是我在迭代...... 10x
  • 这是一个 void 函数。一旦我们到达正确的节点,我需要我的函数返回值。我知道你在用全局变量做什么,但是我需要为很多节点做这个,所以没有更干净的方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 2020-12-09
  • 2017-04-17
  • 1970-01-01
相关资源
最近更新 更多