二叉树非递归遍历
二叉树非递归遍历,可以采用堆栈实现,也可以采用非堆栈用指针实现。感觉堆栈实现很像递归实现,只是要自己把节点压入堆栈,弹出堆栈。非堆栈实现也有两种方法,可以在节点结构中添加标志位以显示当前节点是否已经被遍历过,也可以不用标志位,只用指针表示。这里实现了采用堆栈方式和非堆栈非标志位两种方法。
View Code
1 #include <iostream> 2 #include <stack> 3 #include <ctime> 4 #include <random> 5 6 using namespace std; 7 8 template<class T> 9 struct tree_node 10 { 11 T data; 12 tree_node<T> *l_child; 13 tree_node<T> *r_child; 14 tree_node<T> *parent; 15 }; 16 17 /********************************************************************************** 18 Function: // pre_order_stack 19 Description: // 二叉树非递归前序遍历,采用堆栈方法 20 Input: // root: 树节点指针 21 Return: // 无 22 **********************************************************************************/ 23 template<class T> 24 void pre_order_stack(tree_node<T> *root) 25 { 26 stack<tree_node<T> *> node_stack; 27 tree_node<T> *node = root; 28 while(NULL != node || !node_stack.empty()) 29 { 30 if (NULL != node) 31 { 32 cout << node->data << " "; 33 node_stack.push(node); 34 node = node->l_child; 35 } 36 else 37 { 38 node = node_stack.top(); 39 node_stack.pop(); 40 node = node->r_child; 41 } 42 } 43 cout << endl; 44 } 45 46 /********************************************************************************** 47 Function: // pre_order_no_stack 48 Description: // 二叉树非递归前序遍历,非堆栈实现,主要通过两个子节点标志来判断 49 // 当前节点是否已经遍历过了 50 Input: // root: 二叉树节点指针 51 Return: // 无 52 **********************************************************************************/ 53 template<class T> 54 void pre_order_no_stack(tree_node<T> *root) 55 { 56 tree_node<T> *temp = root; 57 //左子节点标志 58 tree_node<T> *tmpl = NULL; 59 //右子结点标志 60 tree_node<T> *tmpr = NULL; 61 while(NULL != temp) 62 { 63 //当前节点没有遍历过,则输出节点数据 64 if ((NULL != temp->l_child && temp->l_child == tmpl) 65 || (NULL != temp->r_child && temp->r_child == tmpr)) 66 { 67 } 68 else 69 { 70 cout << temp->data << " "; 71 } 72 //遍历左子树 73 if(NULL != temp->l_child && tmpl != temp->l_child) 74 { 75 temp = temp->l_child; 76 } 77 //遍历右子树 78 else if (NULL != temp->r_child && tmpr != temp->r_child) 79 { 80 temp = temp->r_child; 81 } 82 //回溯 83 else if(NULL != temp->parent) 84 { 85 //修改节点标志指针 86 if (temp->parent->l_child == temp) 87 { 88 tmpl = temp; 89 } 90 if(temp->parent->r_child == temp) 91 { 92 tmpr = temp; 93 tmpl = temp->parent->l_child; 94 } 95 temp = temp->parent; 96 } 97 else 98 { 99 break; 100 } 101 } 102 cout << endl; 103 } 104 105 /********************************************************************************** 106 Function: // in_order_stack 107 Description: // 二叉树中序遍历堆栈实现版本 108 Input: // root: 二叉树节点 109 Return: // 无 110 **********************************************************************************/ 111 template<class T> 112 void in_order_stack(tree_node<T> *root) 113 { 114 stack<tree_node<T>* > node_stack; 115 tree_node<T> *temp = root; 116 while(NULL != temp || !node_stack.empty()) 117 { 118 if(NULL != temp) 119 { 120 node_stack.push(temp); 121 temp = temp->l_child; 122 } 123 else 124 { 125 temp = node_stack.top(); 126 cout << temp->data << " "; 127 node_stack.pop(); 128 temp = temp->r_child; 129 } 130 } 131 cout << endl; 132 } 133 134 /********************************************************************************** 135 Function: // in_order_no_stack 136 Description: // 二叉树非递归非堆栈中序遍历 137 Input: // root: 二叉树节点指针 138 Return: // 无 139 **********************************************************************************/ 140 template<class T> 141 void in_order_no_stack(tree_node<T> *root) 142 { 143 tree_node<T> *temp = root; 144 //左子节点标志 145 tree_node<T> *tmpl = NULL; 146 //右子结点标志 147 tree_node<T> *tmpr = NULL; 148 while (NULL != temp) 149 { 150 //遍历左子树 151 if (NULL != temp->l_child && temp->l_child != tmpl) 152 { 153 temp = temp->l_child; 154 } 155 else 156 { 157 //当前节点没有遍历过,则输出节点数据,中序遍历要先遍历左子树之后才能遍历当前节点 158 if (temp->l_child == tmpl && !(NULL != tmpr && temp->r_child == tmpr)) 159 { 160 cout << temp->data << " "; 161 } 162 //遍历右子树 163 if(NULL != temp->r_child && temp->r_child != tmpr) 164 { 165 temp = temp->r_child; 166 tmpl = NULL; 167 } 168 else 169 { 170 //修改节点标志指针 171 if(NULL != temp->parent) 172 { 173 if (temp == temp->parent->l_child) 174 { 175 tmpl = temp; 176 } 177 else 178 { 179 tmpr = temp; 180 tmpl = temp->parent->l_child; 181 } 182 temp = temp->parent; 183 } 184 else 185 { 186 break; 187 } 188 } 189 } 190 } 191 cout << endl; 192 } 193 194 /********************************************************************************** 195 Function: // post_order_stack 196 Description: // 二叉树非递归后序遍历堆栈实现版 197 Input: // root: 二叉树节点 198 Return: // 无 199 **********************************************************************************/ 200 template<class T> 201 void post_order_stack(tree_node<T> *root) 202 { 203 if (NULL == root) 204 { 205 return; 206 } 207 stack<tree_node<T>*> node_stack; 208 tree_node<T> *temp = root; 209 tree_node<T> *tmpl = NULL; 210 tree_node<T> *tmpr = NULL; 211 while(NULL != temp || !node_stack.empty()) 212 { 213 if(NULL != temp->l_child && tmpl != temp->l_child) 214 { 215 node_stack.push(temp); 216 temp = temp->l_child; 217 } 218 else if (NULL != temp->r_child && tmpr != temp->r_child) 219 { 220 node_stack.push(temp); 221 temp = temp->r_child; 222 } 223 else 224 { 225 cout << temp->data << " "; 226 if(!node_stack.empty()) 227 { 228 if(temp == node_stack.top()->l_child) 229 { 230 tmpl = temp; 231 } 232 else 233 { 234 tmpr = temp; 235 tmpl = temp->parent->l_child; 236 } 237 temp = node_stack.top(); 238 node_stack.pop(); 239 if (temp == root && tmpr == temp->r_child) 240 { 241 cout << temp->data << " "; 242 break; 243 } 244 } 245 else 246 { 247 break; 248 } 249 } 250 } 251 cout << endl; 252 } 253 254 /********************************************************************************** 255 Function: // post_order_stack 256 Description: // 二叉树非递归后序遍历非堆栈实现版 257 Input: // root: 二叉树节点 258 Return: // 无 259 **********************************************************************************/ 260 template<class T> 261 void post_order_no_stack(tree_node<T> *root) 262 { 263 tree_node<T> *temp = root; 264 tree_node<T> *tmpl = NULL; 265 tree_node<T> *tmpr = NULL; 266 while(NULL != temp) 267 { 268 if(temp->l_child != NULL && tmpl != temp->l_child) 269 { 270 temp = temp->l_child; 271 tmpl = NULL; 272 tmpr = NULL; 273 } 274 else if(NULL != temp->r_child && tmpr != temp->r_child) 275 { 276 temp = temp->r_child; 277 tmpl = NULL; 278 tmpr = NULL; 279 } 280 else 281 { 282 if(temp->l_child == tmpl && temp->r_child == tmpr) 283 { 284 cout << temp->data << " "; 285 } 286 if(NULL != temp->parent) 287 { 288 if(temp == temp->parent->l_child) 289 { 290 tmpl = temp; 291 tmpr = NULL; 292 } 293 else 294 { 295 tmpr = temp; 296 tmpl = temp->parent->l_child; 297 } 298 temp = temp->parent; 299 } 300 else 301 { 302 break; 303 } 304 } 305 } 306 } 307 308 /********************************************************************************** 309 Function: // insert_node 310 Description: // 输出数组的最小前n个数 311 Input: // root: 二叉树节点 312 // data: 节点中的数据 313 Return: // 无 314 **********************************************************************************/ 315 template<class T> 316 void insert_node(tree_node<T> *&root, T data) 317 { 318 tree_node<T> *new_node = new tree_node<T>; 319 new_node->data = data; 320 new_node->l_child = NULL; 321 new_node->parent = NULL; 322 new_node->r_child = NULL; 323 if (root == NULL) 324 { 325 root = new_node; 326 } 327 else 328 { 329 tree_node<T> *temp = root; 330 tree_node<T> *tmp; 331 while(NULL != temp) 332 { 333 tmp = temp; 334 if(data > temp->data) 335 { 336 temp = temp->r_child; 337 } 338 else 339 { 340 temp = temp->l_child; 341 } 342 } 343 if (data > tmp->data) 344 { 345 tmp->r_child = new_node; 346 } 347 else 348 { 349 tmp->l_child = new_node; 350 } 351 new_node->parent = tmp; 352 } 353 } 354 355 /********************************************************************************** 356 Function: // delete_tree 357 Description: // 删除整个树 358 Input: // root: 二叉树节点 359 Return: // 无 360 **********************************************************************************/ 361 template<class T> 362 void delete_tree(tree_node<T> *root) 363 { 364 if(NULL != root) 365 { 366 delete_tree(root->l_child); 367 delete_tree(root->r_child); 368 delete root; 369 } 370 } 371 372 373 int main() 374 { 375 tree_node<int> *root = NULL; 376 srand(time(0)); 377 for(int i = 0; i < 10; ++i) 378 { 379 insert_node(root, rand() % 20); 380 } 381 //insert_node(root, 6); 382 //insert_node(root, 9); 383 //insert_node(root, 11); 384 //insert_node(root, 4); 385 //insert_node(root, 8); 386 //insert_node(root, 3); 387 //insert_node(root, 5); 388 pre_order_stack(root); 389 pre_order_no_stack(root); 390 in_order_stack(root); 391 in_order_no_stack(root); 392 post_order_stack(root); 393 post_order_no_stack(root); 394 delete_tree(root); 395 return 0; 396 }