二叉搜索树的结点添加算法

一开始没有看书没有查,自己写了一个,花了好久才调试成功:

 1 bool BST::Add_Node(TreeNode* temp) {
 2     if (!root) {
 3         root = temp;
 4         return true;
 5     }
 6     TreeNode* current = root;
 7     while (!current->childLess()) {
 8         if (temp->getData() >= current->getData()) {
 9             if (current->getRightChild())
10                 current = current->getRightChild();
11             else
12                 break;
13         }
14         else if (temp->getData() < current->getData()) {
15             if (current->getLeftChild())
16                 current = current->getLeftChild();
17             else
18                 break;
19         }
20         else if (current == root)
21             break;
22         else return false;
23     }
24     if (temp->getData() < current->getData())
25         current->setLeftChild(temp);
26     else
27         current->setRightChild(temp);
28     temp->setParent(current);
29     return true;

结点数据:

 构造成功后数据结构应该如图所示:

 这里对于有重复键值的结点的加入是这样的:(见8-12行)允许重复值的加入,如碰到相同值的结点,则将当前指针指向这个结点的右孩子。

其实这里对二叉搜索树的定义参考的是《算法导论》,其中是允许重复值的:

 如果想排除重复值,略微修改代码即可,很容易,不再叙述。

以上算法通过先序遍历验证,成功:

 再看《算法导论》中对于结点添加算法的描述:

 它用了一个辅助值y,代码要比我自己写的稍微简洁些。我们来按照这个伪代码修改一下自己的代码:

 1 bool BST::Add_Node(TreeNode* temp) {
 2     if (!root) {
 3         root = temp;
 4         return true;
 5     }
 6     TreeNode* assist = NULL;
 7     TreeNode* current = root;
 8     while (current) {
 9         assist = current;
10         if (temp->getData() >= current->getData()) {
11             if (current->getRightChild())
12                 current = current->getRightChild();
13             else
14                 break;
15         }
16         else if (temp->getData() < current->getData()) {
17             if (current->getLeftChild())
18                 current = current->getLeftChild();
19             else
20                 break;
21         }
22         else return false;
23     }
24     temp->setParent(assist);
25     if (temp->getData() < current->getData())
26         current->setLeftChild(temp);
27     else
28         current->setRightChild(temp);
29     return true;
30 }

呃,其实没什么区别···算法思路是一样的,如果当前结点值大于新的值,就走左边;如果新的值大于当前结点值,就走右边。走到底,然后把新结点加上去。

先序遍历验证以上代码,成功:

猜你喜欢

转载自www.cnblogs.com/mrlonely2018/p/11954459.html