【说明】:
本文是左程云老师所著的《程序员面试代码指南》第三章中“遍历二叉树的神级方法”这一题目的C++复现。
本文只包含问题描述、C++代码的实现以及简单的思路,不包含解析说明,具体的问题解析请参考原书。
感谢左程云老师的支持。
【题目】:
给定一个二叉树的头节点 head,完成二叉树的先序、中序和后序遍历。如果二叉树的节点数为N,要求时间复杂度为O(N),额外的空间复杂度为O(1)。
【思路】:
解法:Morris 遍历方法,利用空节点。
【编译环境】:
CentOS6.7(x86_64)
gcc 4.4.7
【实现及测试】:
声明代码:
1 /* 2 *Filename:bt_morris.h 3 *Author: 4 *Summary:Use Morris method to traversing binary tree. 5 */ 6 7 #include <iostream> 8 using namespace std; 9 10 class Node 11 { 12 public: 13 Node(int data) 14 { 15 value = data; 16 left = NULL; 17 right = NULL; 18 } 19 public: 20 int value; 21 Node *left; 22 Node *right; 23 }; 24 25 void morrisIn(Node *head); // inorder traversal 26 void morrisPre(Node *head); // preorder traversal 27 void morrisPos(Node *head); // posorder traversal
实现及测试代码:
1 /* 2 *Filename:bt_morris.h 3 *Author: 4 *Summary:Use Morris method to traversing binary tree. 5 */ 6 7 #include "bt_morris.h" 8 9 10 void morrisIn(Node *head) 11 { 12 if (NULL == head) 13 return; 14 15 Node *cur1 = head; 16 Node *cur2 = NULL; 17 while (NULL != cur1) 18 { 19 cur2 = cur1->left; // cur2 is cur1's left node. 20 if (NULL != cur2) 21 { 22 while(NULL != cur2->right && cur2->right != cur1) //Find rightmost node of cur2 and detect if this node point to cur1. 23 { 24 cur2 = cur2->right; 25 } 26 if (NULL == cur2->right) 27 { 28 cur2->right = cur1; // Make the rightmost node's right-node(NULL) point to cur2. 29 cur1 = cur1->left; // Continue until cur1's left node is NULL. 30 continue; 31 } 32 else 33 { 34 cur2->right = NULL; 35 } 36 } 37 cout << cur1->value << " "; //Print node cur1. 38 cur1 = cur1->right; //Move to the cur1's right node. 39 } 40 cout << endl; 41 } 42 43 44 void morrisPre(Node *head) 45 { 46 if (NULL == head) 47 return; 48 49 Node *cur1 = head; 50 Node *cur2 = NULL; 51 while (NULL != cur1) 52 { 53 cur2 = cur1->left; // cur2 is cur1's left node. 54 if (NULL != cur2) 55 { 56 while(NULL != cur2->right && cur2->right != cur1) //Find rightmost node of cur2 and detect if this node point to cur1. 57 { 58 cur2 = cur2->right; 59 } 60 if (NULL == cur2->right) 61 { 62 cur2->right = cur1; // Make the rightmost node's right-node(NULL) point to cur2. 63 cout << cur1->value << " "; //Print node cur1. 64 cur1 = cur1->left; // Continue until cur1's left node is NULL. 65 continue; 66 } 67 else 68 { 69 cur2->right = NULL; 70 } 71 } 72 else 73 { 74 cout << cur1->value << " "; 75 } 76 cur1 = cur1->right; //Move to the cur1's right node. 77 } 78 cout << endl; 79 } 80 81 82 Node* reverseEdge(Node *from) //Since node from, reverse the right border. 83 { 84 Node *pre = NULL; 85 Node *next = NULL; 86 while(NULL != from) 87 { 88 next = from->right; 89 from->right = pre; 90 pre = from; 91 from = next; 92 } 93 return pre; //In the end, node pre (the rightmost node), become the head of the border. 94 95 } 96 97 void printEdge(Node *head) 98 { 99 Node *tail = reverseEdge(head); 100 Node *cur = tail; 101 while(NULL != cur) 102 { 103 cout << cur->value << " "; 104 cur = cur->right; 105 } 106 reverseEdge(tail); //reverse and reverse, the border change back to the original. 107 return; 108 } 109 110 111 void morrisPos(Node *head) 112 { 113 if (NULL == head) 114 return; 115 116 Node *cur1 = head; 117 Node *cur2 = NULL; 118 while (NULL != cur1) 119 { 120 cur2 = cur1->left; // cur2 is cur1's left node. 121 if (NULL != cur2) 122 { 123 while(NULL != cur2->right && cur2->right != cur1) //Find rightmost node of cur2 and detect if this node point to cur1. 124 { 125 cur2 = cur2->right; 126 } 127 if (NULL == cur2->right) 128 { 129 cur2->right = cur1; // Make the rightmost node's right-node(NULL) point to cur2. 130 cur1 = cur1->left; // Continue until cur1's left node is NULL. 131 continue; 132 } 133 else 134 { 135 cur2->right = NULL; 136 printEdge(cur1->left); 137 } 138 } 139 cur1 = cur1->right; //Move to the cur1's right node. 140 } 141 printEdge(head); 142 cout << endl; 143 } 144 145 void createBT(Node **head,int arr[],int len,int index=0) 146 { 147 if(index > len-1 || -1 == arr[index] ) 148 return; 149 (*head) = new Node(arr[index]); 150 createBT(&((*head)->left),arr,len,2*index+1); 151 createBT(&((*head)->right),arr,len,2*index+2); 152 } 153 154 int main() 155 { 156 int arr[] = {1,2,3,4,5,6,7}; 157 Node *root = NULL; 158 createBT(&root,arr,7); 159 morrisIn(root); 160 morrisPre(root); 161 morrisPos(root); 162 163 return 0; 164 }
注:
转载请注明出处;
转载请注明源思路来自于左程云老师的《程序员代码面试指南》。