初级木遁忍术‘树界降临’掌握完毕。

    一心追逐无上忍术的我,准备学习进阶的忍术 木遁-森罗万象!

              ------------------ switch -------------------

    中级篇

     综述二叉查找树的类框架及各种眼花缭乱的DFS递归。

     二叉树类的逻辑思维要求较高,细节要求较严谨。 此篇代码大部摘自著作 《数据结构与算法分析 C++描述》。     此类通过公有函数对私有函数的调用及私有函数的递归运用,巧妙实现了二叉树的构建,查找,删除等功能。

     以下是代码框架。后续给出部分私有函数的实现代码,详细参见原著。

 

 1 //类模板需支持比较运算符
 2 template <typename Comparable>
 3 class BinarySearchTree
 4 {
 5 private:
 6     struct BinaryNode
 7     {
 8         Comparable element;
 9         BinaryNode* left;
10         BinaryNode* right;
11         BinaryNode(const Comparable& _el = Comparable(), BinaryNode* _le = NULL, BinaryNode* _ri = NULL)
12             :element(_el), left(_le), right(_ri) {}
13     };
14 public:
15     //三大函数
16     BinarySearchTree() {}
17     BinarySearchTree(const BinarySearchTree& rhs)
18     {
19         if (this != &rhs) *this = rhs;
20     }
21     BinarySearchTree operator = (const BinarySearchTree& rhs)
22     {
23         if (this != &rhs)
24         {
25             makeEmpty();
26             root = clone(rhs.root);
27         }
28         return *this;
29     }
30     //析构函数
31     ~BinarySearchTree() { makeEmpty(); }
32     //求最小值
33     const Comparable& findMin() const
34     {
35         return findMin(root)->element;
36     }
37     //求最大值
38     const Comparable& findMax() const
39     {
40         return findMax(root)->element;
41     }
42     //是否含有指定元素
43     bool contains(const Comparable& t) const
44     {
45         contains(t, root);
46     }
47     //插入指定元素
48     void insert(const Comparable& t)
49     {
50         insert(t, root);
51     }
52     //删除指定元素
53     void remove(const Comparable& t)
54     {
55         remove(t, root);
56     }
57     //打印树(默认中序遍历/inorder traversal)
58     void printTree() const
59     {
60         printTree(root);
61     }
62     //是否为空树
63     bool isEmpty() const
64     {
65         return root == NULL ? true : false;
66     }
67     //删除树
68     void makeEmpty()
69     {
70         makeEmpty(root);
71     }
72 private:
73     BinaryNode* root; //根节点
74         // ... ... private methods ... ...
75 };

 

      简略讲下私有函数bool contains(const ComparablexBinaryNodetconst 的递归调用。

      递归代码的简洁性有时会让刚接触递归的人感到迷惑,其实并不难理解。

      程序以 t == NULL 为递归界限,进行DFS。若不符合条件,调用递归函数。

      代码如下。

 

1 bool contains(const Comparable& x, BinaryNode* t) const
2     {
3         if (t == NULL) return false;
4         else if (t->element > x) return contains(x, t->right);
5         else if (t->element < x) return contains(x, t->left);
6         else return true;  //找到 x
7     }

 

     十分简洁,下面是其他私有函数的实现。

 

 1     void insert(const Comparable& x, BinaryNode*& t)
 2     {
 3         if (t == NULL) t = new BinaryNode(x);
 4         else if (t->element > x) insert(x, t->right);
 5         else if (t->element < x) insert(x, t->left);
 6         else   //树中存在待插入的元素
 7             ;
 8     }
 9     void remove(const Comparable& x, BinaryNode*& t)
10     {
11         if (t == NULL) return; //树为空或者(递归到叶结点)不存在待删除的元素时
12         if (t->element > x)  remove(x, t->right);
13         else if (t->element < x)  remove(x, t->left);
14         else if (t->left != NULL && t->right != NULL) //找到待删除的结点,且有两个子树
15         {
16             t->element = findMin(t->right)->element;
17             remove(t->element, t->right);   //该步骤可以写一个void removeMin(const Comparable& x,BinaryNode*)函数提高效率
18             /*void removeMin(const Comparable& x,BinaryNode* t)
19             {
20                 if (t == NULL) return;
21                 if (t->left == NULL)
22                 {
23                     BinaryNode* oldNode = t;
24                     t = (t->left == NULL) ? t->left : t->right;
25                     delete oldNode;
26                 }
27                 else  removeMin(t->left);  //若未找到
28             }*/
29 
30         } 
31         else  //找到待删除的结点,只有一个子树
32         {
33             BinaryNode* oldNode = t;
34             t = (t->left != NULL) ? t->left : t->right;
35             delete oldNode;
36         }
37     }
38     BinaryNode* findMin(BinaryNode* t) const
39     {
40         //循环版本
41         //if(t)
42         //  while (t->left) t = t->left;
43         //return t;
44         
45         //递归
46         if (t == NULL) return NULL;
47         if (t->left == NULL) return t;
48         return findMin(t->left);
49     }

         可以注意到insert和remove的传递参数是指针的引用,而findMin则是传递指针。

         这细微的"Shitf + 7"的区别,是值得细细品味的。

posted on 2016-08-09 01:25  Elapsed_Time  阅读(201)  评论(0编辑  收藏  举报