二叉查找树
一 二叉查找树的性质
二叉查找树(BinarySearchTree)是满足如下性质的一种二叉树:对于树中的每个节点n,它的左子树中所有节点的值不大于n的值,它的右子树中所有节点的值不小于n的值。
二 二叉查找树的节点
二叉查找树内封装了二叉查找树的节点,节点的域包括data, left, right, parent。
下面的代码是二叉树节点的结构体声明:
1 struct BinaryTreeNode 2 { 3 Comparable data; 4 BinaryTreeNode *left; 5 BinaryTreeNode *right; 6 BinaryTreeNode *parent; 7 8 BinaryTreeNode(Comparable d, BinaryTreeNode *l=NULL, BinaryTreeNode *r=NULL, BinaryTreeNode *p=NULL): data(d), left(l), right(r), parent(p) { } 9 };
其中,Comparable为模板类型,需要重载">"、"<"、"=="、"<<"等运算符。
三 二叉查找树应该具备的操作
public:
其他如构造函数、析构函数、操作符重载
⑧ 从子树中移除节点 void removeNode(node)
1 #include <iostream> 2 3 using namespace std; 4 5 //Comparable必须重载 ① '>' ② '<' ③ '==' ④ '<<' 6 template <typename Comparable> 7 class BinarySearchTree 8 { 9 public: 10 BinarySearchTree() { root = NULL; } 11 BinarySearchTree(const BinarySearchTree *bst) { root = deepClone(bst->root); } 12 ~BinarySearchTree() { makeEmpty(); } 13 14 BinarySearchTree* operator=(const BinarySearchTree *bst) 15 { 16 this->root = deepClone(bst->root); 17 return this; 18 } 19 20 void makeEmpty() 21 { 22 makeEmpty(root); 23 } 24 25 void insert(Comparable d) 26 { 27 //方法一 28 BinaryTreeNode *r = root; 29 BinaryTreeNode *p = NULL; 30 31 while (r) 32 { 33 p = r; 34 if (d < r->data) 35 r = r->left; 36 else if (d > r->data) 37 r = r->right; 38 else 39 return; //若数据相同则不插入 40 } 41 r = new BinaryTreeNode(d); 42 if (!p) 43 root = r; 44 else if (d < p->data) 45 p->left = r; 46 else 47 p->right = r; 48 r->parent = p; 49 //方法二 50 /* 51 if (root) 52 insertNode(d, root); 53 else 54 root = new BinaryTreeNode(d); 55 */ 56 } 57 58 void printTree() 59 { 60 if (root) 61 { 62 printTree(root); 63 cout << endl; 64 } 65 else 66 cout << "树中没有数据" << endl; 67 } 68 69 private: 70 struct BinaryTreeNode 71 { 72 Comparable data; 73 BinaryTreeNode *left; 74 BinaryTreeNode *right; 75 BinaryTreeNode *parent; 76 77 BinaryTreeNode(Comparable d, BinaryTreeNode *l=NULL, BinaryTreeNode *r=NULL, BinaryTreeNode *p=NULL): data(d), left(l), right(r), parent(p) { } 78 }; 79 80 BinaryTreeNode *root; 81 82 BinaryTreeNode* deepClone(BinaryTreeNode *n) 83 { 84 if (n) 85 { 86 BinaryTreeNode *p = new BinaryTreeNode(n->data, deepClone(n->left), deepClone(n->right)); 87 if (p->left) 88 p->left->parent = p; 89 if (p->right) 90 p->right->parent = p; 91 return p; 92 } 93 return NULL; 94 } 95 96 void makeEmpty(BinaryTreeNode *&n) // 需要改变指针参数 97 { 98 if (n) 99 { 100 makeEmpty(n->left); 101 makeEmpty(n->right); 102 delete n; 103 n = NULL; 104 } 105 return; 106 } 107 108 void insertNode(Comparable d, BinaryTreeNode *n) 109 { 110 if (d < n->data) 111 { 112 if (n->left) 113 insertNode(d, n->left); 114 else 115 { 116 n->left = new BinaryTreeNode(d); 117 n->left->parent = n; 118 } 119 } 120 else if (d > n->data) 121 { 122 if (n->right) 123 insertNode(d, n->right); 124 else 125 { 126 n->right = new BinaryTreeNode(d); 127 n->right->parent = n; 128 } 129 } 130 else 131 ; 132 return; 133 } 134 135 void printTree(BinaryTreeNode *r) 136 { 137 if (!r) 138 return; 139 printTree(r->left); 140 cout << r->data << " "; 141 printTree(r->right); 142 } 143 };
我们着重分析其中的四个操作:
1.1 insert插入数据
插入数据可以用两种方式实现:非递归方式、递归方式,但其实两种方式的思想是一样的:根据数值大小找到应该插入的位置。需要注意的是,插入时需要检测是否有根节点。
为了更简单地表达二叉查找树,可以使二叉树内数据各异,即若插入的数据在二叉树中已有,则不插入。
下面我用代码分别实现这两种方式:
1.1.1 非递归方式
1 void insert(Comparable d) 2 { 3 BinaryTreeNode *r = root; 4 BinaryTreeNode *p = NULL; 5 6 while (r) 7 { 8 p = r; 9 if (d < r->data) 10 r = r->left; 11 else if (d > r->data) 12 r = r->right; 13 else 14 return; //若数据相同则不插入 15 } 16 r = new BinaryTreeNode(d); 17 if (!p) 18 root = r; 19 else if (d < p->data) 20 p->left = r; 21 else 22 p->right = r; 23 r->parent = p; 24 }
1.1.2 递归方式
1 void insert(Comparable d) 2 { 3 if (root) 4 insertNode(d, root); 5 else 6 root = new BinaryTreeNode(d); 7 } 8 9 void insertNode(Comparable d, BinaryTreeNode *n) 10 { 11 if (d < n->data) 12 { 13 if (n->left) 14 insertNode(d, n->left); 15 else 16 { 17 n->left = new BinaryTreeNode(d); 18 n->left->parent = n; 19 } 20 } 21 else if (d > n->data) 22 { 23 if (n->right) 24 insertNode(d, n->right); 25 else 26 { 27 n->right = new BinaryTreeNode(d); 28 n->right->parent = n; 29 } 30 } 31 else 32 ; 33 return; 34 }
1.2 deepClone深拷贝
深拷贝采用了递归的方式实现。
1 BinaryTreeNode* deepClone(BinaryTreeNode *n) 2 { 3 if (n) 4 { 5 BinaryTreeNode *p = new BinaryTreeNode(n->data, deepClone(n->left), deepClone(n->right)); 6 if (p->left) 7 p->left->parent = p; 8 if (p->right) 9 p->right->parent = p; 10 return p; 11 } 12 return NULL; 13 }
1.3 printTree打印数据
由二叉查找树的性质可知,若我们中序遍历二叉树,会得到已排序好的数据。
1 void printTree() 2 { 3 if (root) 4 { 5 printTree(root); 6 cout << endl; 7 } 8 else 9 cout << "树中没有数据" << endl; 10 } 11 12 void printTree(BinaryTreeNode *r) 13 { 14 if (!r) 15 return; 16 printTree(r->left); 17 cout << r->data << " "; 18 printTree(r->right); 19 }
1.4 makeEmpty清空树操作
清空树操作的思想采用递归思想,即首先递归删除该节点的左子树和右子树,然后再删除本节点。
需要注意的是,在清空树之后,需要把根节点root设置为NULL。
1 void makeEmpty() 2 { 3 makeEmpty(root); 4 } 5 6 void makeEmpty(BinaryTreeNode *&n) // 需要改变指针参数 7 { 8 if (n) 9 { 10 makeEmpty(n->left); 11 makeEmpty(n->right); 12 delete n; 13 n = NULL; 14 } 15 return; 16 }
2 实现BinarySearchTree的删除数据操作
删除数据时需要找到对应的节点并删除,所以需要搜索操作。而由于删除节点需要寻找前趋节点或者后继节点,而寻找前趋/后继节点又需要需找子树的最大/最小数据节点,所以将这5个操作一并介绍。这些操作都可以分为非递归、递归的实现方式,就不分开讲了。
2.1 searchNode寻找节点
寻找节点与插入节点的思想一样,都是根据数据大小选择向左子树或右子树继续操作。搜索节点也可以递归的方式实现。
1 BinaryTreeNode* searchNode(Comparable d) 2 { 3 BinaryTreeNode *r = root; 4 while (r) 5 { 6 if (d < r->data) 7 r = r->left; 8 else if (d > r->data) 9 r = r->right; 10 else 11 return r; 12 } 13 return NULL; 14 }
2.2 findMin寻找最小数据(节点)
没什么好说的,根据二叉搜索树的性质,一直向左子树寻找。
1 Comparable findMin() 2 { 3 // 方法一 4 BinaryTreeNode *r = root; 5 BinaryTreeNode *p = NULL; 6 while (r) 7 { 8 p = r; 9 r = r->left; 10 } 11 if (p) 12 return p->data; 13 else 14 return -1; 15 // 方法二 16 //return findMinNode(root)->data; 17 } 18 19 BinaryTreeNode* findMinNode(BinaryTreeNode *n) 20 { 21 if (n->left) 22 return findMinNode(n->left); 23 return n; 24 }
2.3 findMax寻找最大数据(节点)
也没什么好说的,根据二叉搜索树的性质,一直向右子树寻找。
1 Comparable findMax() 2 { 3 // 方法一 4 BinaryTreeNode *r = root; 5 BinaryTreeNode *p = NULL; 6 while (r) 7 { 8 p = r; 9 r = r->right; 10 } 11 if (p) 12 return p->data; 13 else 14 return -1; 15 // 方法二 16 //return findMaxNode(root)->data; 17 } 18 19 BinaryTreeNode* findMaxNode(BinaryTreeNode *n) 20 { 21 if (n->right) 22 return findMaxNode(n->right); 23 return n; 24 }
2.4 findPredecessor寻找前趋数据(节点)
寻找前趋数据时分两种情况。
我们假定该节点为n,前趋节点为p,则有
① 若节点n存在左子树,则显然n的左子树中数据最大的节点为前趋节点
② 若节点n不存在左子树,则需要向上搜索找到满足以下条件的节点p:节点n在节点p的右子树中。若向上搜索时,子节点n为父节点p的左子树,则继续向上搜索,直到节点p为NULL。
1 Comparable findPredecessor(Comparable d) 2 { 3 BinaryTreeNode *n = searchNode(d); 4 if (n) 5 { 6 BinaryTreeNode *pre = findPredeNode(n); 7 8 if (pre) 9 return pre->data; 10 else 11 return n->data; 12 } 13 else 14 return d; 15 } 16 17 BinaryTreeNode* findPredeNode(BinaryTreeNode *n) 18 { 19 BinaryTreeNode *p = NULL; 20 if (n->left) 21 return findMaxNode(n->left); 22 p = n->parent; 23 while (p && n == p->left) 24 { 25 n = p; 26 p = p->parent; 27 } 28 return p; 29 }
2.5 findSuccessor寻找后继数据(节点)
寻找后继数据时分两种情况。
我们假定该节点为n,后继节点为p,则有
① 若节点n存在右子树,则显然n的右子树中数据最小的节点为后继节点
② 若节点n不存在右子树,则需要向上搜索找到满足以下条件的节点p:节点n在节点p的左子树中。若向上搜索时,子节点n为父节点p的右子树,则继续向上搜索,直到节点p为NULL。
1 Comparable findSuccessor(Comparable d) 2 { 3 BinaryTreeNode *n = searchNode(d); 4 if (n) 5 { 6 BinaryTreeNode *suc = findSucNode(n); 7 8 if (suc) 9 return suc->data; 10 else 11 return n->data; 12 } 13 else 14 return d; 15 } 16 17 BinaryTreeNode* findSucNode(BinaryTreeNode *n) 18 { 19 BinaryTreeNode *p = NULL; 20 if (n->right) 21 return findMinNode(n->right); 22 p = n->parent; 23 while (p && n == p->right) 24 { 25 n = p; 26 p = p->parent; 27 } 28 return p; 29 }
2.6 删除数据(节点)
删除节点是分三种情况。
我们假定被删除的节点为n,n节点的父节点为p,则有:
① 被删除节点没有子节点,这个最简单,直接删了就可以,同时将p的相关子节点域left/right改为NULL
② 被删除节点只有一个子节点,这个也简单,将该节点的父节点与子节点相连即可,同时将p的相关子节点域left/right为NULL、子节点的父节点域parent为p。
③ 被删除节点有两个子节点,这个稍微有点麻烦,不过可以换个思路解决。即不是真正的删除这个节点,而是将节点n的前趋或后继节点的数据拷贝过来,然后转而删除节点n的前趋或后继节点,一般使用后继节点。若后继节点仍然有两个节点,则一直向下搜索,直到将情况③转换为情况①②。
情况①②的代码可以合并优化,同时还是需要特别注意根节点,若被删除的节点是根节点root,则直接将其子节点重新设置为root,不需要也不能够修改子节点域left/right和父节点域parent。
1 void remove(Comparable d) 2 { 3 BinaryTreeNode *n = searchNode(d); 4 5 if (n != NULL) 6 { 7 //方法一 8 while (n->left && n->right) 9 { 10 n->data = findSucNode(n)->data; 11 n = findSucNode(n); 12 } 13 14 BinaryTreeNode *x = (n->left) ? n->left : n->right; 15 if (n == root) 16 root = x; 17 else 18 { 19 if (n == n->parent->left) 20 n->parent->left = x; 21 else 22 n->parent->right = x; 23 if (x) 24 x->parent = n->parent; 25 } 26 delete n; 27 //方法二 28 //removeNode(n); 29 } 30 } 31 32 void removeNode(BinaryTreeNode *n) 33 { 34 if (!n) 35 return; 36 if (n->left && n->right) 37 { 38 n->data = findPredeNode(n)->data; 39 removeNode(findPredeNode(n)); 40 //n->data = findSucNode(n)->data; 41 //removeNode(findSucNode(n)); 42 } 43 else 44 { 45 BinaryTreeNode *x = (n->left) ? n->left : n->right; 46 if (n == root) 47 root = x; 48 else 49 { 50 if (n == n->parent->left) 51 n->parent->left = x; 52 else 53 n->parent->right = x; 54 if (x) 55 x->parent = n->parent; 56 } 57 delete n; 58 } 59 }
3 其他操作,如contains检测是否包含某数据、isEmpty检测是否为空。
检测是否包含数据,只要检测searchNode()返回的指针是否为空;检测是否为空,只要检测根节点root是否为空。
五 完整代码
5.1 BinarySearchTree.hpp
1 #include <iostream> 2 3 using namespace std; 4 5 //Comparable必须重载 ① '>' ② '<' ③ '==' ④ '<<' 6 template <typename Comparable> 7 class BinarySearchTree 8 { 9 public: 10 BinarySearchTree() { root = NULL; } 11 BinarySearchTree(const BinarySearchTree *bst) { root = deepClone(bst->root); } 12 ~BinarySearchTree() { makeEmpty(); } 13 14 BinarySearchTree* operator=(const BinarySearchTree *bst) 15 { 16 this->root = deepClone(bst->root); 17 return this; 18 } 19 20 Comparable findMin() 21 { 22 // 方法一 23 BinaryTreeNode *r = root; 24 BinaryTreeNode *p = NULL; 25 while (r) 26 { 27 p = r; 28 r = r->left; 29 } 30 if (p) 31 return p->data; 32 else 33 return -1; 34 // 方法二 35 //return findMinNode(root)->data; 36 } 37 38 Comparable findMax() 39 { 40 // 方法一 41 BinaryTreeNode *r = root; 42 BinaryTreeNode *p = NULL; 43 while (r) 44 { 45 p = r; 46 r = r->right; 47 } 48 if (p) 49 return p->data; 50 else 51 return -1; 52 // 方法二 53 //return findMaxNode(root)->data; 54 } 55 56 bool contains(Comparable d) 57 { 58 // 方法一 59 BinaryTreeNode *r = root; 60 while (r) 61 { 62 if (d < r->data) 63 r = r->left; 64 else if (d > r->data) 65 r = r->right; 66 else 67 return true; 68 } 69 return false; 70 // 方法二 71 //return searchNode(d) ? true : false; 72 } 73 74 Comparable findPredecessor(Comparable d) 75 { 76 BinaryTreeNode *n = searchNode(d); 77 if (n) 78 { 79 BinaryTreeNode *pre = findPredeNode(n); 80 81 if (pre) 82 return pre->data; 83 else 84 return n->data; 85 } 86 else 87 return d; 88 } 89 90 Comparable findSuccessor(Comparable d) 91 { 92 BinaryTreeNode *n = searchNode(d); 93 if (n) 94 { 95 BinaryTreeNode *suc = findSucNode(n); 96 97 if (suc) 98 return suc->data; 99 else 100 return n->data; 101 } 102 else 103 return d; 104 } 105 106 bool isEmpty() 107 { 108 return root ? false : true; 109 } 110 111 void makeEmpty() 112 { 113 makeEmpty(root); 114 } 115 116 void insert(Comparable d) 117 { 118 //方法一 119 BinaryTreeNode *r = root; 120 BinaryTreeNode *p = NULL; 121 122 while (r) 123 { 124 p = r; 125 if (d < r->data) 126 r = r->left; 127 else if (d > r->data) 128 r = r->right; 129 else 130 return; //若数据相同则不插入 131 } 132 r = new BinaryTreeNode(d); 133 if (!p) 134 root = r; 135 else if (d < p->data) 136 p->left = r; 137 else 138 p->right = r; 139 r->parent = p; 140 //方法二 141 /* 142 if (root) 143 insertNode(d, root); 144 else 145 root = new BinaryTreeNode(d); 146 */ 147 } 148 149 void remove(Comparable d) 150 { 151 BinaryTreeNode *n = searchNode(d); 152 153 if (n != NULL) 154 { 155 //方法一 156 while (n->left && n->right) 157 { 158 n->data = findSucNode(n)->data; 159 n = findSucNode(n); 160 } 161 162 BinaryTreeNode *x = (n->left) ? n->left : n->right; 163 if (n == root) 164 root = x; 165 else 166 { 167 if (n == n->parent->left) 168 n->parent->left = x; 169 else 170 n->parent->right = x; 171 if (x) 172 x->parent = n->parent; 173 } 174 delete n; 175 //方法二 176 //removeNode(n); 177 } 178 } 179 180 void printTree() 181 { 182 if (root) 183 { 184 printTree(root); 185 cout << endl; 186 } 187 else 188 cout << "树中没有数据" << endl; 189 } 190 191 private: 192 struct BinaryTreeNode 193 { 194 Comparable data; 195 BinaryTreeNode *left; 196 BinaryTreeNode *right; 197 BinaryTreeNode *parent; 198 199 BinaryTreeNode(Comparable d, BinaryTreeNode *l=NULL, BinaryTreeNode *r=NULL, BinaryTreeNode *p=NULL): data(d), left(l), right(r), parent(p) { } 200 }; 201 202 BinaryTreeNode *root; 203 204 BinaryTreeNode* deepClone(BinaryTreeNode *n) 205 { 206 if (n) 207 { 208 BinaryTreeNode *p = new BinaryTreeNode(n->data, deepClone(n->left), deepClone(n->right)); 209 if (p->left) 210 p->left->parent = p; 211 if (p->right) 212 p->right->parent = p; 213 return p; 214 } 215 return NULL; 216 } 217 218 BinaryTreeNode* findMinNode(BinaryTreeNode *n) 219 { 220 if (n->left) 221 return findMinNode(n->left); 222 return n; 223 } 224 225 BinaryTreeNode* findMaxNode(BinaryTreeNode *n) 226 { 227 if (n->right) 228 return findMaxNode(n->right); 229 return n; 230 } 231 232 BinaryTreeNode* searchNode(Comparable d) 233 { 234 BinaryTreeNode *r = root; 235 while (r) 236 { 237 if (d < r->data) 238 r = r->left; 239 else if (d > r->data) 240 r = r->right; 241 else 242 return r; 243 } 244 return NULL; 245 } 246 247 BinaryTreeNode* findPredeNode(BinaryTreeNode *n) 248 { 249 BinaryTreeNode *p = NULL; 250 if (n->left) 251 return findMaxNode(n->left); 252 p = n->parent; 253 while (p && n == p->left) 254 { 255 n = p; 256 p = p->parent; 257 } 258 return p; 259 } 260 261 BinaryTreeNode* findSucNode(BinaryTreeNode *n) 262 { 263 BinaryTreeNode *p = NULL; 264 if (n->right) 265 return findMinNode(n->right); 266 p = n->parent; 267 while (p && n == p->right) 268 { 269 n = p; 270 p = p->parent; 271 } 272 return p; 273 } 274 275 void makeEmpty(BinaryTreeNode *&n) // 需要改变指针参数 276 { 277 if (n) 278 { 279 makeEmpty(n->left); 280 makeEmpty(n->right); 281 delete n; 282 n = NULL; 283 } 284 return; 285 } 286 287 void insertNode(Comparable d, BinaryTreeNode *n) 288 { 289 if (d < n->data) 290 { 291 if (n->left) 292 insertNode(d, n->left); 293 else 294 { 295 n->left = new BinaryTreeNode(d); 296 n->left->parent = n; 297 } 298 } 299 else if (d > n->data) 300 { 301 if (n->right) 302 insertNode(d, n->right); 303 else 304 { 305 n->right = new BinaryTreeNode(d); 306 n->right->parent = n; 307 } 308 } 309 else 310 ; 311 return; 312 } 313 314 void removeNode(BinaryTreeNode *n) 315 { 316 if (!n) 317 return; 318 if (n->left && n->right) 319 { 320 n->data = findPredeNode(n)->data; 321 removeNode(findPredeNode(n)); 322 //n->data = findSucNode(n)->data; 323 //removeNode(findSucNode(n)); 324 } 325 else 326 { 327 BinaryTreeNode *x = (n->left) ? n->left : n->right; 328 if (n == root) 329 root = x; 330 else 331 { 332 if (n == n->parent->left) 333 n->parent->left = x; 334 else 335 n->parent->right = x; 336 if (x) 337 x->parent = n->parent; 338 } 339 delete n; 340 } 341 } 342 343 void printTree(BinaryTreeNode *r) 344 { 345 if (!r) 346 return; 347 printTree(r->left); 348 cout << r->data << " "; 349 printTree(r->right); 350 } 351 };
5.2 main.cpp
1 #include <ctime> 2 #include <iostream> 3 #include <cstdlib> 4 5 #include "BinarySearchTree.hpp" 6 7 using namespace std; 8 9 const int LENGTH = 8; 10 11 void generateTree(BinarySearchTree<int> *tree) 12 { 13 srand((unsigned int)time(NULL)); 14 int i = LENGTH; 15 while(i--) 16 { 17 tree->insert(rand() % 100); 18 } 19 } 20 21 void checkDeepClone(BinarySearchTree<int> *tree) 22 { 23 BinarySearchTree<int> *newTree = tree; 24 //BinarySearchTree<int> *newTree = new BinarySearchTree<int>(tree); 25 cout << "数据拷贝完成" << endl; 26 newTree->printTree(); 27 } 28 29 void checkMinMax(BinarySearchTree<int> *tree) 30 { 31 cout << "Min: " << tree->findMin() << endl; 32 cout << "Max: " << tree->findMax() << endl; 33 } 34 35 void checkContains(BinarySearchTree<int> *tree) 36 { 37 int elem; 38 cout << "请输入用来测试是否包含的数据: "; 39 cin >> elem; 40 if (tree->contains(elem)) 41 cout << "存在" << endl; 42 else 43 cout << "不存在" << endl; 44 } 45 46 void checkPreSuc(BinarySearchTree<int> *tree) 47 { 48 int elem; 49 cout << "请输入用来测试前趋后继的数据: "; 50 cin >> elem; 51 cout << elem << "的前趋为" << tree->findPredecessor(elem) << endl; 52 cout << elem << "的后继为" << tree->findSuccessor(elem) << endl; 53 } 54 55 void checkEmpty(BinarySearchTree<int> *tree) 56 { 57 if (tree->isEmpty()) 58 cout << "树为空" << endl; 59 else 60 cout << "树不为空" << endl; 61 62 tree->makeEmpty(); 63 tree->printTree(); 64 65 if (tree->isEmpty()) 66 cout << "树为空" << endl; 67 else 68 cout << "树不为空" << endl; 69 } 70 71 void checkRemove(BinarySearchTree<int> *tree) 72 { 73 if (tree->isEmpty()) 74 { 75 generateTree(tree); 76 tree->printTree(); 77 } 78 while (!tree->isEmpty()) 79 { 80 int elem; 81 cout << "请输入要移除的数据: "; 82 cin >> elem; 83 tree->remove(elem); 84 tree->printTree(); 85 86 } 87 } 88 89 int main() 90 { 91 BinarySearchTree<int> *tree = new BinarySearchTree<int>(); 92 generateTree(tree); 93 tree->printTree(); 94 95 checkDeepClone(tree); 96 97 checkMinMax(tree); 98 99 checkContains(tree); 100 checkContains(tree); 101 102 checkPreSuc(tree); 103 checkPreSuc(tree); 104 checkPreSuc(tree); 105 checkPreSuc(tree); 106 107 checkEmpty(tree); 108 109 checkRemove(tree); 110 111 system("pause"); 112 }
5.3 运行结果截图
另外,发现有的递归可以以非递归的方式实现,而有的递归不能转化为非递归方式。
可以将递归转化为非递归的递归称为"尾递归"。尾部递归的函数有助将算法转化成函数编程语言,而且从编译器角度来说,亦容易优化成为普通循环。