二进制搜索树切换子树

时间:2015-05-03 00:29:37

标签: c

所以我正在尝试编写一个函数,当给出两个指向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;
}

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

任何人都可以指出我所犯的任何错误,并指出我正确的方向吗?

感谢!!!

1 个答案:

答案 0 :(得分:1)

你的问题在这里:

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

正确的应该是:

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

否则{2}后a->parent永远丢失。

错误的做法

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 |-+               
+------+    +---+                 +---+