遍历二叉树的神级方法

【说明】:

  本文是左程云老师所著的《程序员面试代码指南》第三章中“遍历二叉树的神级方法”这一题目的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
View Code

  实现及测试代码:

  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 }
View Code

 

注:

  转载请注明出处;

  转载请注明源思路来自于左程云老师的《程序员代码面试指南》。

posted @ 2016-07-28 21:21  PrimeLife  阅读(621)  评论(0编辑  收藏  举报