【说明】:
本文是左程云老师所著的《程序员面试代码指南》第三章中“分别用递归和非递归方式实现二叉树先序、中序和后序遍历”这一题目的C++复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
用递归和非递归的方式,分别按照二叉树先序、中序和后序打印所有的节点。我们约定:先序遍历顺序为根、左、右;中序遍历顺序为左、根、右;后序遍历顺序为左、右、根。
【思路】:
解法:堆归的方式大家肯定都比较熟悉了。但是非递归的方式逻辑上还是蛮复杂的,从代码推敲推敲吧.........(去买本左老师的书也可以啊)^_^ ^_^ ^_^
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现及测试】:
声明代码:
1 /* 2 *文件名:bt_traversing.h 3 *作者: 4 *摘要:分别用递归和非递归的方式实现二叉树的先序、中序和后序遍历 5 */ 6 7 #ifndef _BT_TRAVERSING 8 #define _BT_TRAVERSING 9 #include <iostream> 10 using namespace std; 11 12 class Node 13 { 14 public: 15 Node(int data) 16 { 17 value = data; 18 left = NULL; 19 right = NULL; 20 } 21 public: 22 int value; 23 Node *left; 24 Node *right; 25 }; 26 27 //递归版 28 void preOrderRecur(Node *head); 29 void inOrderRecur(Node *head); 30 void posOrderRecur(Node *head); 31 32 //非递归版 33 void preOrderUnRecur(Node *head); 34 void inOrderUnRecur(Node *head); 35 void posOrderUnRecur1(Node *head); 36 void posOrderUnRecur2(Node *head); 37 38 #endif
实现代码:
1 /* 2 *文件名:bt_traversing.cpp 3 *作者: 4 *摘要:分别用递归和非递归的方式实现二叉树的先序、中序和后序遍历 5 */ 6 7 #include "bt_traversing.h" 8 #include <iostream> 9 #include <stack> 10 11 using namespace std; 12 13 void preOrderRecur(Node *head) 14 { 15 if(NULL == head) 16 return ; 17 cout << head->value << " "; 18 preOrderRecur(head->left); 19 preOrderRecur(head->right); 20 } 21 22 void inOrderRecur(Node *head) 23 { 24 if(NULL == head) 25 return ; 26 inOrderRecur(head->left); 27 cout << head->value << " "; 28 inOrderRecur(head->right); 29 } 30 31 void posOrderRecur(Node *head) 32 { 33 if(NULL == head) 34 return ; 35 posOrderRecur(head->left); 36 posOrderRecur(head->right); 37 cout << head->value << " "; 38 } 39 40 void preOrderUnRecur(Node *head) 41 { 42 if(NULL != head) 43 { 44 stack<Node*> s; 45 s.push(head); 46 while(!s.empty()) 47 { 48 head = s.top(); 49 s.pop(); 50 cout << head->value << " "; 51 if(NULL != head->right) 52 s.push(head->right); 53 if(NULL != head->left) 54 s.push(head->left); 55 } 56 } 57 cout << endl; 58 return ; 59 } 60 61 void inOrderUnRecur(Node *head) 62 { 63 if(NULL != head) 64 { 65 stack<Node*> s; 66 while(!s.empty() || NULL != head) 67 { 68 if(NULL != head) 69 { 70 s.push(head); 71 head = head->left; 72 } 73 else 74 { 75 head = s.top(); 76 s.pop(); 77 cout << head->value << " "; 78 head = head->right; 79 } 80 } 81 } 82 cout << endl; 83 return ; 84 } 85 86 void posOrderUnRecur1(Node *head) 87 { 88 if(NULL != head) 89 { 90 stack<Node*> s1; 91 stack<Node*> s2; 92 s1.push(head); 93 while(!s1.empty()) 94 { 95 head = s1.top(); 96 s1.pop(); 97 s2.push(head); 98 if(NULL != head->left) 99 s1.push(head->left); 100 if(NULL != head->right) 101 s1.push(head->right); 102 } 103 while(!s2.empty()) 104 { 105 cout << s2.top()->value << " "; 106 s2.pop(); 107 } 108 } 109 cout << endl; 110 return ; 111 } 112 113 void posOrderUnRecur2(Node *head) 114 { 115 if(NULL != head) 116 { 117 stack<Node*> s; 118 s.push(head); 119 Node *cur = NULL; 120 while(!s.empty()) 121 { 122 cur = s.top(); 123 if(NULL != cur->left && head != cur->left && head != cur->right) 124 s.push(cur->left); 125 else if(NULL != cur->right && head != cur->right) 126 s.push(cur->right); 127 else 128 { 129 cout << s.top()->value << " "; 130 s.pop(); 131 head = cur; 132 } 133 } 134 } 135 cout << endl; 136 return ; 137 138 }
测试代码:
1 /* 2 *文件名:main.cpp 3 *作者: 4 *摘要:测试代码 5 */ 6 7 #include "bt_traversing.h" 8 #include <iostream> 9 using namespace std; 10 11 //由数组创建完全二叉树 12 void createBT(Node **head,int arr[],int len,int index=0) 13 { 14 if(index > len-1) 15 return; 16 (*head) = new Node(arr[index]); 17 createBT(&((*head)->left),arr,len,2*index+1); 18 createBT(&((*head)->right),arr,len,2*index+2); 19 } 20 21 int main() 22 { 23 int arr[] = {1,2,3,4,5,6,7,8,9}; 24 Node *head = NULL; 25 createBT(&head,arr,9); 26 27 cout << "Using recursive method to achieve pre-order traversal:" << endl; 28 preOrderRecur(head); 29 cout << endl; 30 cout << "Using recursive method to achieve in-order traversal:" << endl; 31 inOrderRecur(head); 32 cout << endl; 33 cout << "Using recursive method to achieve pos-order traversal:" << endl; 34 posOrderRecur(head); 35 cout << endl; 36 37 cout << "Without using recursive way to achieve the pre-order traversal:"<< endl; 38 preOrderUnRecur(head); 39 cout << "Without using recursive way to achieve the in-order traversal:"<< endl; 40 inOrderUnRecur(head); 41 cout << "The first method achieve the pos-order traversal without using recursive:"<< endl; 42 posOrderUnRecur1(head); 43 cout << "The second method achieve the pos-order traversal without using recursive:"<< endl; 44 posOrderUnRecur2(head); 45 return 0; 46 }
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。