【Weiss】【第04章】二叉搜索树例程

【二叉搜索树】

随机生成时平均深度为logN,平均插入、删除和搜索时间都是O(logN)。

可能存在的问题是数据不均衡,使树单边生长,极端情况下变成类似链表,最坏插入、删除、搜索时间O(N)

 

写这个例程也花了些时间,例程主要包括查找、插入、删除、遍历、清空几个内容。

同时避免之前写链表到了半途再修改,拷贝构造、拷贝赋值、析构也写成了深拷贝的模式。

光这两份代码在一起还无法运行,因为层序遍历那一块用了之前写的队列例程。

 

测试代码:

 1 #include <iostream>
 2 #include "bstree.h"
 3 using bstree::BSTree;
 4 int main(void)
 5 {
 6     //测试插入
 7     BSTree<int> number;
 8     cout << "additem" << endl;
 9     number.additem(8);number.additem(4);number.additem(17);number.additem(3);
10     number.additem(6);number.additem(10);number.additem(18);number.additem(2);
11     number.additem(5);number.additem(7);number.additem(9);number.additem(15);
12     number.additem(19);number.additem(1);number.additem(14);number.additem(16);
13     number.additem(20); number.additem(13); number.additem(11); number.additem(12);
14     //打印
15     number.printpre();
16     cout << "--preorder"<<endl;
17     number.printin();
18     cout << "--inorder" << endl;
19     number.printpost();
20     cout << "--postorder" << endl;
21     number.printseq();
22     cout << "--seqorder" << endl;
23 
24     //测试拷贝构造函数
25     cout << "\ncopy constructor" << endl;
26     BSTree<int> number2(number);
27     number2.printpre();
28     cout << "--preorder" << endl;
29     number2.printin();
30     cout << "--inorder" << endl;
31 
32     //测试插入重复元素
33     cout << "\ncollision" << endl;
34     number.additem(1);
35 
36     //删除测试
37     //删除节点没有右子树
38     cout << "\nremove number 3: iter->right = nullptr" << endl;
39     number.remove(3);
40     number.printpre();
41     cout << "--preorder" << endl;
42     number.printin();
43     cout << "--inorder" << endl;
44 
45     //删除测试
46     //删除节点的右子树没有左子树
47     cout << "\nremove number 15: iter->right->left = nullptr" << endl;
48     number.remove(15);
49     number.printpre();
50     cout << "--preorder" << endl;
51     number.printin();
52     cout << "--inorder" << endl;
53 
54     //删除测试
55     //删除节点的右子树有左子树
56     cout << "\nremove number 10: iter->right->left != nullptr" << endl;
57     number.remove(10);
58     number.printpre();
59     cout << "--preorder" << endl;
60     number.printin();
61     cout << "--inorder" << endl;
62 
63     //删除测试
64     //删除根
65     cout << "\nremove number 8: iter == root" << endl;
66     number.remove(8);
67     number.printpre();
68     cout << "--preorder" << endl;
69     number.printin();
70     cout << "--inorder" << endl;
71 
72     //删除测试
73     //删除不存在的元素
74     cout << "\nremove number not existed" << endl;
75     number.remove(21);
76 
77     //查找最值
78     cout << "\nmax = " << number.findmax()->data << endl;
79     cout << "min = " << number.findmin()->data << endl;
80 
81     //清空树,并测试在空树下删除
82     cout << "\nclear" << endl;
83     number.clear();
84     number.remove(3);
85 
86     system("pause");
87 }
View Code

实现代码:

  1 #ifndef BINARYSEARCHTREE
  2 #define BINARYSEARCHTREE
  3 #include <iostream>
  4 #include "queue.h"
  5 using queue::Queue;
  6 using std::cout;
  7 using std::cin;
  8 using std::endl;
  9 using std::string;
 10 using std::flush;
 11 namespace bstree
 12 {
 13 template <typename T> struct Node
 14 {
 15     Node<T>() : left(nullptr), right(nullptr){}
 16     Node<T>(const T &item) : data(item), left(nullptr), right(nullptr){}
 17     T data;
 18     Node<T>* left;
 19     Node<T>* right;
 20 };
 21 template <typename T> class BSTree
 22 {
 23 //构造函数
 24 public:
 25     BSTree() :nodes(0), root(nullptr){}
 26     BSTree(const BSTree& another)
 27     {
 28         root = nullptr;
 29         nodes = 0;
 30         void(BSTree::*pf)(const Node<T>*);
 31         pf = &BSTree::additem_from_another;
 32         traverse_seq(another.root, pf);
 33     }
 34     ~BSTree(){ clear(); }
 35     BSTree& operator=(const BSTree& another)
 36     {
 37         if (&another != this)
 38         {
 39             clear();
 40             void(BSTree::*pf)(const Node<T>*);
 41             pf = &BSTree::additem_from_another;
 42             traverse_seq(another.root, pf);
 43         }
 44     }
 45 //接口
 46 public:
 47     //元素个数
 48     unsigned int size()const{ return nodes; }
 49     //是否空
 50     bool empty()const{ return noodes == 0; }
 51     //获得根指针
 52     Node<T>* getroot()const{ return root; }
 53     //各种遍历
 54     //前中后序使用辅助函数递归完成,层序遍历需使用队列结构
 55     void printpre()const{ traverse(root, printnode, 0); }
 56     void printin()const{ traverse(root, printnode, 1); }
 57     void printpost()const{ traverse(root, printnode, 2); }
 58     void printseq()const{ traverse_seq(root, printnode); }
 59     //#查找元素
 60     Node<T>* find(const T &item)const;
 61     //#查找最值
 62     Node<T>* findmax()const;
 63     Node<T>* findmin()const;
 64     //#增加元素
 65     bool additem(const T &item);
 66     //#删除元素
 67     bool remove(const T &item);
 68     //清空树并将数据初始化
 69     void clear(){ release(root); root = nullptr; nodes = 0; }
 70 
 71 //辅助函数
 72 private:
 73     void release(Node<T>* iter);
 74     Node<T>* find_prev(const T &item)const;
 75     Node<T>* remove_node(Node<T>* iter);
 76     void traverse(const Node<T>* iter, void(*fp)(const Node<T>*), int mode)const;
 77     void traverse_seq(const Node<T>* iter, void(BSTree::*pf)(const Node<T>*));
 78     void traverse_seq(const Node<T>* iter, void(*pf)(const Node<T>*))const;
 79     void additem_from_another(const Node<T>* iter){ additem(iter->data); }
 80 //数据
 81 private:
 82     Node<T>* root;
 83     unsigned int nodes;
 84 };
 85 
 86 //辅助函数,打印节点元素
 87 template <typename T> static void printnode(const Node<T>* iter){ cout << iter->data << " " << flush; }
 88 //辅助函数
 89 //查找元素的父树。如果树为空或元素为根,返回空指针;如果元素不存在,返回插入该元素时的父树
 90 template <typename T> Node<T>* BSTree<T>::find_prev(const T &item)const
 91 {
 92     Node<T>* prev = nullptr;
 93     Node<T>* curr = root;
 94     while (curr != nullptr)
 95     {
 96         if (item < curr->data)
 97         {
 98             prev = curr;
 99             curr = curr->left;
100         }
101         else if (item > curr->data)
102         {
103             prev = curr;
104             curr = curr->right;
105         }
106         else
107             break;
108     }
109     return prev;
110 }
111 //查找元素,如果元素不存在则返回空指针
112 template <typename T> Node<T>* BSTree<T>::find(const T &item)const
113 {
114     Node<T>* iter = find_prev(item);
115     if (iter == nullptr)
116         return root;
117     if (item < iter->data)
118         return iter->left;
119     else
120         return iter->right;
121 }
122 //查找最值
123 template <typename T> Node<T>* BSTree<T>::findmax()const
124 {
125     if (nodes == 0)
126         return nullptr;
127     Node<T>* iter = root;
128     while (iter->right != nullptr)
129         iter = iter->right;
130     return iter;
131 }
132 template <typename T> Node<T>* BSTree<T>::findmin()const
133 {
134     if (nodes == 0)
135         return nullptr;
136     Node<T>* iter = root;
137     while (iter->left != nullptr)
138         iter = iter->left;
139     return iter;
140 }
141 //插入元素,元素重复则报错
142 template <typename T> bool BSTree<T>::additem(const T &item)
143 {
144     Node<T>* prev = nullptr;
145     Node<T>* curr = root;
146     //找到待插入元素应该插入的位置
147     while (curr != nullptr)
148     {
149         if (item < curr->data)
150         {
151             prev = curr;
152             curr = curr->left;
153         }
154         else if (item > curr->data)
155         {
156             prev = curr;
157             curr = curr->right;
158         }
159         //元素相等导致冲突则报错
160         else        
161         {
162             cout << "Elements collision!" << endl;
163             return false;
164         }
165     }
166     Node<T>* pnew = new Node<T>(item);
167     if (prev == nullptr)
168         root = pnew;
169     else if (item < prev->data)
170         prev->left = pnew;
171     else
172         prev->right = pnew;
173     ++nodes;
174     return true;
175 
176 }
177 //删除元素
178 template <typename T> bool BSTree<T>::remove(const T &item)
179 {
180     if (nodes == 0)
181     {
182         cout << "Tree is empty!" << endl;
183         return false;
184     }
185     //函数主体执行查找操作
186     //查找到相应删除点后,交给remove_node()处理
187     Node<T>* iter = find_prev(item);
188     if (iter == nullptr)
189     {
190         if (root->data != item)
191         {
192             cout << "Not Found!" << endl;
193             return false;
194         }
195         root = remove_node(root);
196     }
197     else if (item < iter->data)
198     {
199         if (iter->left == nullptr)
200         {
201             cout << " Not Found!" << endl;
202             return false;
203         }
204         iter->left = remove_node(iter->left);
205     }
206     else
207     {
208         if (iter->right == nullptr)
209         {
210             cout << "Not Found!" << endl;
211             return false;
212         }
213         iter->right = remove_node(iter->right);
214     }
215     --nodes;
216     return true;
217 }
218 //辅助函数,删除具体节点
219 template <typename T> Node<T>* BSTree<T>::remove_node(Node<T>* iter)
220 {
221     //用即将被删除节点的右子树的最左边的子节点替代即将被删除的位置
222     //情况一,删除节点无右子树
223     if (iter->right == nullptr)
224     {
225         Node<T>* save = iter->left;
226         delete iter;
227         return save;
228     }
229     //情况二,删除节点的右子书无左子树
230     else if (iter->right->left == nullptr)
231     {
232         Node<T>* save = iter->right;
233         save->left = iter->left;
234         delete iter;
235         return save;
236     }
237     //情况三,删除节点的右子树有左子树
238     else
239     {
240         Node<T>* prev = iter->right;
241         Node<T>* curr = iter->right->left;
242         while (curr->left != nullptr)
243         {
244             prev = curr;
245             curr = curr->left;
246         }
247         prev->left = curr->right;
248         curr->left = iter->left;
249         curr->right = iter->right;
250         delete iter;
251         return curr;
252     }
253 }
254 //辅助函数,前中后遍历执行模式
255 template <typename T> void BSTree<T>::traverse(const Node<T>* iter, void(*fp)(const Node<T>*), int mode)const
256 {
257     if (iter == nullptr)
258         return;
259     if (mode == 0)
260     {
261         (*fp)(iter);
262         traverse(iter->left, fp, 0);
263         traverse(iter->right, fp, 0);
264     }
265     else if (mode == 1)
266     {
267         traverse(iter->left, fp, 1);
268         (*fp)(iter);
269         traverse(iter->right, fp, 1);
270     }
271     else if (mode == 2)
272     {
273         traverse(iter->left, fp, 2);
274         traverse(iter->right, fp, 2);
275         (*fp)(iter);
276     }
277     return;
278 }
279 //辅助函数,层序遍历,需队列辅助
280 //重载两个版本,一个用于遍历树不需改变树元素,调用非成员函数printnode。则标记const,函数参数为(*pf)
281 //另一个用于拷贝构造与拷贝赋值需改变树元素,调用成员函数。则不标记const,显示声明调用成员函数(BSTree::*pf)
282 template <typename T> void BSTree<T>::traverse_seq(const Node<T>* iter, void(BSTree::*pf)(const Node<T>*))
283 {
284     if (iter != nullptr)
285     {
286         Queue<const decltype(iter)> node_address;
287         node_address.enqueue(iter);
288         while (!node_address.empty())
289         {
290             const Node<T>* temp = node_address.getfirst();
291             node_address.dequeue();
292             if (temp->left != nullptr)
293                 node_address.enqueue(temp->left);
294             if (temp->right != nullptr)
295                 node_address.enqueue(temp->right);
296             (this->*pf)(temp);
297         }
298     }
299 }
300 template <typename T> void BSTree<T>::traverse_seq(const Node<T>* iter, void(*pf)(const Node<T>*))const
301 {
302     if (iter != nullptr)
303     {
304         Queue<const decltype(iter)> node_address;
305         node_address.enqueue(iter);
306         while (!node_address.empty())
307         {
308             const Node<T>* temp = node_address.getfirst();
309             node_address.dequeue();
310             if (temp->left != nullptr)
311                 node_address.enqueue(temp->left);
312             if (temp->right != nullptr)
313                 node_address.enqueue(temp->right);
314             (*pf)(temp);
315         }
316     }
317 }
318 //辅助函数,释放所有节点清空内存
319 template <typename T> void BSTree<T>::release(Node<T>* iter)
320 {
321     if (iter == nullptr)
322         return;
323     release(iter->left);
324     release(iter->right);
325     delete(iter);
326 }
327 }
328 #endif

 

posted @ 2015-03-21 05:02  猫薄荷喂狗  阅读(297)  评论(0编辑  收藏  举报