1、什么是树?
树是一种典型的数据结构,如下图所示。一棵树由一个称作根的节点和他的非空子树构成,每一颗子树的根节点成为根的儿子。图中,B,C,D就是根A的儿子。A就是B,C,D的父节点,E,F是B的儿子,B是E,F的父节点,A是E,F祖父节点。
2、什么是二叉查找树?
而二叉树是树中的一种特例,他所有的节点最多只有两个儿子。而二叉查找树则是对二叉树进一步限定,他要求节点X的左子树的所有关键字都不大于X节点的关键字,他的右子树所有关键字都不小于X的关键字。下图就是一个二叉查找树。
二叉树的平均深度为O(logN),除了makeEmpty外对二叉查找树其他操作平均时间为O(logN)。
本文用C++实现简单的二叉查找树。其中某些函数有两个版本,一个是用于内部调用,一个是用于外部调用。绝大多数函数都是通过递归实现,这也显示出递归的强大。
其中:clone函数的巧妙应用实现了操作符的重载
1 /* 二叉寻找树的实现 */ 2 /************************************************************************/ 3 #ifndef BINARYSEARHTREE_H 4 #define BINARYSEARHTREE_H 5 6 //定义模板 7 template <typename Comparable> 8 class BinarySearchTree 9 { 10 public: 11 //构造函数 12 BinarySearchTree() 13 { 14 root = new TreeNode; 15 } 16 17 //析构函数,回收内存 18 ~ BinarySearchTree() 19 { 20 makeEmpty(root); 21 } 22 23 //拷贝构造函数 24 BinarySearchTree(const BinarySearchTree& tree) 25 { 26 root = new TreeNode; 27 *this = tree; 28 } 29 30 //重载赋值运算符,进行深层次拷贝 31 BinarySearchTree& operator = (const BinarySearchTree & tree) 32 { 33 makeEmpty(); 34 root = clone(tree.root); //通过clone函数完成数据拷贝 35 return *this; 36 } 37 38 //判断树是否为空 39 bool isEmpty() const 40 { 41 return (root->left == NULL) || (root->right == NULL); 42 } 43 44 //寻找最大的元素,递归实现 45 TreeNode* findmax() const 46 { 47 if (root == NULL) 48 { 49 return NULL; 50 } 51 if (root->right == NULL) 52 { 53 return root; 54 } 55 root->right->findmax(); 56 } 57 58 //寻找最小的元素,循环实现 59 TreeNode* findmin() const 60 { 61 TreeNode* temp = root; 62 if (temp == NULL) 63 { 64 return NULL; 65 } 66 while (temp->left == NULL) 67 { 68 temp = temp->left; 69 } 70 return temp->element; 71 } 72 73 74 //查找,调用内部版本 75 bool find(const Comparable & object) const 76 { 77 return find(object, root); 78 } 79 80 //插入,调用内部版本 81 void insert(const Comparable & object) 82 { 83 return insert(object, root); 84 } 85 private: 86 struct TreeNode //树节点结构体 87 { 88 Comparable element; //节点关键字 89 TreeNode* left; //左儿子节点指针 90 TreeNode* right; //右儿子节点指针 91 92 TreeNode(Comparable c = Comparable(), TreeNode* l = NULL, TreeNode* r = NULL) 93 :element(c), left(l), right(r){ } 94 }; 95 96 TreeNode* root; //树的根节点指针 97 98 99 /* 二叉查找树的查找,采用内部版本和外部版本是为了解决外部版本不能访问成员变量的问题*/ 100 bool find(const Camparable & object, TreeNode* t) const 101 { 102 if (t == NULL) 103 { 104 return false; 105 } 106 //递归调用 107 if (root->element >object) 108 { 109 find(object, root->right); 110 } 111 else if (root->element < object) 112 { 113 find(object, root->left); 114 } 115 else 116 { 117 return true; 118 } 119 } 120 121 /*插入函数*/ 122 void insert(const Comparable & object, TreeNode* t) 123 { 124 //分配一个结点空间 125 if (t == NULL) 126 { 127 t = new TreeNode(object); 128 return; 129 } 130 //递归插入 131 if (root->element > object) 132 { 133 insert(object, t->left); 134 } 135 else if(root->element < object) 136 { 137 insert(object, t->right); 138 } 139 else 140 { 141 //do nothing 142 } 143 } 144 145 //删除节点 146 void remove(const Comparable & object, TreeNode* t) 147 { 148 //判断是否为空 149 if (t == NULL) 150 { 151 return; 152 } 153 //递归调用左右儿子 154 if (t->element >object) 155 { 156 remove(object, t->right); 157 } 158 else if (t->element < object) 159 { 160 remove(object, t->left); 161 } 162 //找到对象 163 else if(root->left != NULL && root->right != NULL) //处理有两个儿子的情况 164 { 165 Comparable ret = findmin(root->right)->element; //找到右子树中最小的那个,代替删除的节点 166 t->element = ret; 167 remove(ret, t->right); //删除那个子节点 168 } 169 else //处理一个儿子的情况 170 { 171 TreeNode* old = t; 172 t = (t->left != NULL) ? t->left : t->right; 173 delete old; 174 } 175 } 176 177 void makeEmpty(TreeNode* t) 178 { 179 if (t == NULL) 180 { 181 return; 182 } 183 makeEmpty(t->left); 184 makeEmpty(t->right); 185 delete t; 186 t = NULL; 187 } 188 189 TreeNode * clone( TreeNode* t) const 190 { 191 if (t == NULL) 192 { 193 return NULL; 194 } 195 return new TreeNode(t->element, t->left, t->right); 196 } 197 }; 198 199 #endif