• 遍历二叉树的神级方法


    【说明】:

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

    注:

      转载请注明出处;

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

  • 相关阅读:
    从高版本JDK换成低版本JDK报错Unsupported major.minor version 52.0
    永远不要祈求生活来怜悯你,你只能让自己变的更强
    69 个经典 Spring 面试题和答案
    Jackson 框架,轻易转换JSON
    Apache Commons Codec 编码解码
    演讲
    Shiro源码分析-初始化-Realm
    各个JSON技术的比较
    常见数据库设计(2)——历史数据问题之单记录变更
    fiddler
  • 原文地址:https://www.cnblogs.com/PrimeLife/p/5716282.html
Copyright © 2020-2023  润新知