1 #include <iostream>
2
3 using namespace std;
4
5 template <typename K, typename V>
6 class BST
7 {
8 private:
9 struct node // 类内定义类、结构体
10 {
11 K key;
12 V value;
13 node *left = nullptr;
14 node *right = nullptr;
15 };
16 node * root = nullptr;
17 node * putB(node *rootp, K key, V value); // 注意不能把这个函数放在公有区,因为node是一个私有变量,如果外部调用putB会出问题,且只有成员函数会调用这个函数,没必要声明为公有的就不要声明为公有
18 public:
19 BST(/* args */);
20 void putA(K key, V value);
21 void putB(K key, V value);
22 /* void putB(node *&rootp, K key, V value); */ //类内定义结构体不用加作用域限定: BST<K, V>::node
23
24 V get(K key);
25 V getR(node *rootp, K key); //对于结构相似且头尾相接的数据结构(如这里的二叉树:每个节点都可以是根节点,每个根节点下都有左右节点),要善于利用递归
26 bool max(K &key, V &value);
27 bool min(K &key, V &value);
28 int rank(K key);
29 bool remove(K key);
30 int howMany();
31 void show();
32 void showR(node *p);
33 void free(node *p);
34 ~BST();
35 };
36
37 template <typename K, typename V>
38 BST<K, V>::BST(/* args */)
39 {
40 //did nothing
41 }
42
43 template <typename K, typename V>
44 V BST<K, V>::get(K key)
45 {
46 V val = NULL;
47 val = getR(root, key);
48 if(val != NULL) //warning:val == 0 is equal to val == NULL
49 {
50 cout << "key: " << key << "\t val: " << val << endl;
51 return val;
52 }
53 }
54
55 template <typename K, typename V>
56 V BST<K, V>::getR(node *rootp, K key)
57 {
58 if(rootp == nullptr)
59 {
60 cout << "can't find key[" << key << "]." << endl;
61 return NULL;
62 }
63
64 if(rootp->key == key)
65 return rootp->value;
66 else if(rootp->key < key)
67 {
68 return getR(rootp->right, key);
69 }
70 else
71 return getR(rootp->left, key);
72 }
73
74 /* 循环查找 */
75 template <typename K, typename V>
76 void BST<K, V>::putA(K key, V value)
77 {
78 node **temp = &root; //使用指针的指针,因为下面要给指针分配内存
79 while((*temp) != nullptr)
80 {
81 if((*temp)->key == key)
82 {
83 (*temp)->key = key;
84 (*temp)->value = value;
85 return;
86 }
87 if((*temp)->key > key)
88 temp = &((*temp)->left);
89 else
90 temp = &((*temp)->right);
91 }
92 *temp = (node *)new node;
93 (*temp)->key = key;
94 (*temp)->value = value;
95 }
96
97 template <typename K, typename V>
98 void BST<K, V>::putB(K key, V value)
99 {
100 /* putB(root, key, value); */
101 root = putB(root, key, value);
102 }
103
104 /* 递归查找 */
105 /*
106 template <typename K, typename V>
107 void BST<K, V>::putB(node *&rootp, K key, V value) //指针的引用
108 {
109 if(rootp == nullptr)
110 {
111 rootp = new node;
112 rootp->key = key;
113 rootp->value = value;
114 return;
115 }
116 if(rootp->key == key)
117 {
118 rootp->value = value;
119 return;
120 }
121 else if(rootp->key > key)
122 return putB(rootp->left, key, value);
123 else
124 return putB(rootp->right, key, value);
125
126 }
127 */
128
129 /* 不加typename的话会提示错误: need 'typename' before 'BST<K, V>::node' because 'BST<K, V>' is a dependent scope,原因:c++primer P593 */
130 template <typename K, typename V>
131 typename BST<K, V>::node * BST<K, V>::putB(node *rootp, K key, V value)
132 {
133 if(rootp == nullptr)
134 {
135 rootp = new node;
136 rootp->key = key;
137 rootp->value = value;
138 return rootp;
139 }
140 if(rootp->key == key)
141 {
142 rootp->value = value;
143 }
144 else if(rootp->key > key)
145 rootp->left = putB(rootp->left, key, value);
146 else
147 rootp->right = putB(rootp->right, key, value);
148
149 return rootp;
150 }
151
152 template <typename K, typename V>
153 void BST<K, V>::show()
154 {
155 showR(root);
156 }
157
158 template <typename K, typename V>
159 void BST<K, V>::showR(node *p)
160 {
161 if(p->left != nullptr)
162 showR(p->left);
163 cout << "key: " << p->key << "\tvalue: " << p->value << endl;
164 if(p->right != nullptr)
165 showR(p->right);
166 }
167
168 template <typename K, typename V>
169 void BST<K, V>::free(node *p)
170 {
171 if(p == nullptr)
172 return;
173 free(p->left);
174 free(p->right);
175 delete p;
176 }
177
178 template <typename K, typename V>
179 BST<K, V>::~BST()
180 {
181 free(root);
182 }
183
184 int main()
185 {
186 BST<char, int> container;
187 cout << "before: " << endl;
188 for(int i=0; i<22; ++i)
189 {
190 char k = 65 + rand() % 20;
191 int v = rand() % 100;
192 cout << "k: " << k << " v: " << v << endl;
193 container.putB(k, v);
194 //or container.putA(k, v);
195 }
196
197 container.show();
198
199 char token;
200 cout << "enter key you want to find(0 to exit):";
201 cin >> token;
202 while(token != '0')
203 {
204 container.get(token);
205 cout << "enter key you want to find(0 to exit):";
206 cin >> token;
207 }
208
209 return 0;
210 }