【问题标题】:Binary Search Trees Switching subtrees二叉搜索树切换子树
【发布时间】:2015-05-03 10:08:10
【问题描述】:

所以我正在尝试编写一个函数,当给定两个指向 BST 中节点的指针时,将“切换”子树位置。

typedef struct NODE { 
  struct NODE* parent;
  struct NODE* left;
  struct NODE* right;
}node_t;

这是我用于 BST 的节点结构。

我的功能是:

void switch_subtree(node_t* a, node_t* b)
{
  if (a==NULL || b==NULL)
    {
      return;
    }

  if (a->parent->left == a)
  {
    a->parent->left = b;
  }
  else
  {
    a->parent->right = b;
  }

  if (b->parent->left == b)
  {
    b->parent->left = a;
  }
  else
  {
    b->parent->right = a;
  }

  nodes * temp = a;
  a->parent = b->parent;
  b->parent = temp->parent;
}

但是,当我运行它时,它没有正确切换子树。

谁能指出我犯的任何错误并指出正确的方向?

谢谢!!!

【问题讨论】:

    标签: c


    【解决方案1】:

    你的问题在这里:

    nodes * temp = a;
      a->parent = b->parent;
      b->parent = temp->parent;
    

    正确的应该是:

    nodes * temp = a->parent;
      a->parent = b->parent;
      b->parent = temp;
    

    否则a->parent 在第 2 行之后将永远丢失。

    理由

    错误的方法

    temp = a 行将使 tempa 指针指向同一个 NODE 结构:

                       +- > +--------+      +- > +--------+
                       |    |        |      |    |        |     
                       |    | ...    |      |    | ...    |     
                       |    +--------+      |    +--------+
                       |                    |
                       +--------------+     +----------------+
                                      |                      |
             +--------+- > +--------+ |     +- > +---------+ |
             |        |    | parent |-+     |    | parent  |-+
             |        |    | ...    |       |    | ...     |
             |        |    +--------+       |    +---------+
             |        |                     |
    +------+ |  +---+ |               +---+ |               
    | temp |-+  | a |-+               | b |-+               
    +------+    +---+                 +---+
    

    在第 2 行更改 a->parent (a->parent = b->parent) 也会更改 temp->parent,因为它们只是相同 NODE 结构的相同组件 (parent) 的不同名称:

                           +--------+   +---+- > +--------+
                           |        |   |   |    |        |     
                           | ...    |   |   |    | ...    |     
                           +--------+   |   |    +--------+
                                        |   |
                                        |   +--------------+
                                        |                   |
             +--------+- > +--------+   |   +- > +---------+
             |        |    | parent |---+   |    | parent  |
             |        |    | ...    |       |    | ...     |
             |        |    +--------+       |    +---------+
             |        |                     |
    +------+ |  +---+ |               +---+ |               
    | temp |-+  | a |-+               | b |-+               
    +------+    +---+                 +---+
    

    分配b->parent = temp->parent 根本没有改变任何东西,因为b->parenttemp->parent 已经指向同一个节点。 - 错误!

    另类

    看看建议的替代方案,temp = a->parent 将给您留下如下所示的情况:

             +---------+- > +--------+      +- > +--------+
             |         |    |        |      |    |        |     
             |         |    | ...    |      |    | ...    |     
             |         |    +--------+      |    +--------+
             |         |                    |
             |         +--------------+     +----------------+
             |                        |                      |
             |        +- > +--------+ |     +- > +---------+ |
             |        |    | parent |-+     |    | parent  |-+
             |        |    | ...    |       |    | ...     |
             |        |    +--------+       |    +---------+
             |        |                     |
    +------+ |  +---+ |               +---+ |               
    | temp |-+  | a |-+               | b |-+               
    +------+    +---+                 +---+
    

    a->parent = b->parent之后temp仍然指向a所指向的节点的原始父节点:

             +----------- > +--------+      +- > +--------+
             |              |        |      |    |        |     
             |              | ...    |      |    | ...    |     
             |              +--------+      |    +--------+
             |                              |
             |                        +-----+----------------+
             |                        |                      |
             |        +- > +--------+ |     +- > +---------+ |
             |        |    | parent |-+     |    | parent  |-+
             |        |    | ...    |       |    | ...     |
             |        |    +--------+       |    +---------+
             |        |                     |
    +------+ |  +---+ |               +---+ |               
    | temp |-+  | a |-+               | b |-+               
    +------+    +---+                 +---+
    

    最后分配b->parent = temp会给b指向的节点右父节点:

             +--------+-- > +--------+  +----- > +--------+
             |        |     |        |  |        |        |     
             |        |     | ...    |  |        | ...    |     
             |        |     +--------+  |        +--------+
             |        |                 |
             |        +-----------------|--------------------+
             |                          |                    |
             |        +- > +--------+   |   +- > +---------+ |
             |        |    | parent |---+   |    | parent  |-+
             |        |    | ...    |       |    | ...     |
             |        |    +--------+       |    +---------+
             |        |                     |
    +------+ |  +---+ |               +---+ |               
    | temp |-+  | a |-+               | b |-+               
    +------+    +---+                 +---+
    

    【讨论】:

    • 这是因为 nodes * temp 只是一个指向一个特定位置的指针吗?从而做 nodes * temp = a->parent 允许 temp 直接指向 a->parent?
    • 是的,也许我应该在答案中说得更清楚。我会努力解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    相关资源
    最近更新 更多