LeetCode—— Binary Tree Traversal

二叉树遍历的三道题

Binary Tree Preorder Traversal

Binary Tree Inorder Traversal

Binary Tree Postorder Traversal

LeetCode 上二叉树的节点定义如下:

// 树的节点 struct TreeNode {
      int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode(int x) : val(x), left(nullptr), right(nullptr) { }
};

常规递归算法

/**
 * 递归先序遍历
 */
void preOrder_traverse_recur(BiTree T) {
  if(T == NULL) {
    return;
  } else {
    printf("%d", T->val);
    preOrder_traverse_recur(T->left);
    preOrder_traverse_recur(T->right);
  }
}

/**
 * 递归中序遍历
 */
void inOrder_traverse_recur(BiTree T) {
  if(T == NULL) {
    return;
  } else {
    inOrder_traverse_recur(T->left);
    printf("%d", T->val);
    inOrder_traverse_recur(T->right);
  }
}

/**
 * 递归后序遍历
 */
void postOrder_traverse_recur(BiTree T) {
  if(T == NULL) {
    return;
  } else {
    postOrder_traverse_recur(T->left);
    postOrder_traverse_recur(T->right);
    printf("%d", T->val);
  }
}

栈 算法

时间复杂度 O(n),空间复杂度 O(n)

// LeetCode, Binary Tree Preorder Traversal
class Solution {
public:
      vector<int> preorderTraversal(TreeNode *root) {
          vector<int> result;
          const TreeNode *p;
          stack<const TreeNode *> s;
          p = root;
          if (p != nullptr) s.push(p);
          while (!s.empty()) {
              p = s.top();
              s.pop();
              result.push_back(p->val);
              if (p->right != nullptr) s.push(p->right);
              if (p->left != nullptr) s.push(p->left);
          }
          return result;
      }
};
// LeetCode, Binary Tree Inorder Traversal
class Solution {
public:
      vector<int> inorderTraversal(TreeNode *root) {
          vector<int> result;
          const TreeNode *p = root;
          stack<const TreeNode *> s;
          while (!s.empty() || p != nullptr) {
              if (p != nullptr) {
s.push(p);
                  p = p->left;
              } else {
                  p = s.top();
                  s.pop();
                  result.push_back(p->val);
                  p = p->right;
} }
          return result;
      }
};
// LeetCode, Binary Tree Postorder Traversal
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) { vector<int> result;
/* p,正在访问的结点,q,刚刚访问过的结点 */ const TreeNode *p, *q;
          stack<const TreeNode *> s;
?
5.1 二叉树的遍历 91
?p = root;
do {
while (p != nullptr) { /* 往左下走 */
s.push(p);
p = p->left; }
        q = nullptr;
        while (!s.empty()) {
p = s.top();
s.pop();
/* 右孩子不存在或已被访问,访问之 */ if (p->right == q) {
                result.push_back(p->val);
q = p; /* 保存刚访问过的结点 */ } else {
/* 当前结点不能访问,需第二次进栈 */ s.push(p);
/* 先处理右子树 */
p = p->right;
break; }
        }
    } while (!s.empty());
    return result;
}
};

Morris算法

时间复杂度 O(n),空间复杂度 O(1)

参考:http://www.tuicool.com/articles/zA7NJbj

算法伪码(Morris InOrder) :

while 节点非空
   if 当前节点没有左子树
     访问该节点
     转向右节点
   else
     找到左子树的最右节点
        if 最右子节点指空
            最右节点的右指针指向根
            转向左子树节点
        else //最右子节点指根
            消除指根指针
            根节点右移

C++实现:

Morris 中序遍历

void morris_inorder(TreeNode *root) {
   TreeNode *p = root, *tmp;
   while (p) {
       if (p->left == NULL) {
           printf("%d ", p->key);
           p = p->right;
       }
       else {
           tmp = p->left;
           while (tmp->right != NULL && tmp->right != p)
               tmp = tmp->right;
           if (tmp->right == NULL) {
               tmp->right = p;
               p = p->left;
           } else {
               printf("%d ", p->key);
               tmp->right = NULL;
               p = p->right;
           }
       }
   }
}
Morris 先序遍历

void morris_preorder(TreeNode *root) {
    TreeNode *p = root, *tmp;
    while (p) {
        if (p->left == NULL) {
            printf("%d ",p->key);
            p = p->right;
        } else {
            tmp = p->left;
            while (tmp->right != NULL && tmp->right != p) {
                tmp = tmp->right;
            }
            if (tmp->right == NULL){
                print("%d ",p->key);
                tmp->right = p;
                p = p->left;
            } else {
                tmp->right = NULL;
                p = p->right;
            }
        }
    }
}

Morris后序遍历二叉树的算法与上面的算法思想一致,只是在遍历前,增加了一个类似头节点的节点作为整个遍历过程的起始节点。

/**
 * morris后序遍历算法
 */
void morris_postOrder(BiTree T) {
  BNode *dump = malloc(sizeof(BNode));
  BNode *p, *temp;
  dump->left = T;
  p = dump;
  while(p) {
    if(p->left == NULL) {
      p = p->right;
    } else {
      temp = p->left;
      while(temp->right != NULL && temp->right != p) {
        temp = temp->right;
      }
      if(temp->right == NULL) {
        temp->right = p;
        p = p->left;
      } else {
        printReverse(p->left, temp);
        temp->right = NULL;
        p = p->right;
      }
    }
  }
  free(dump);
}

代码中的printReverse()函数就是逆序遍历从p->left到temp这条路径上的节点的过程;

printReverse函数先将从from节点到to节点的这条路径反转,再输出,最后还原.

/**
 * 相当于单链表的反转
 */
void reverse(BNode *from, BNode *to) {
  BNode *x, *y, *z;
  if(from == to) {
    return;
  }
  x = from;
  y = from->right;
  while(x != to) {
    z = y->right;
    y->right = x;
    x = y;
    y = z;
  }
}

void printReverse(BNode *from , BNode *to) {
  BNode *p;
  reverse(from, to);
  p = to;
  while(1) {
    printf("%4c", p->ch);
    if(p == from) {
      break;
    }
    p = p->right;
  }
  reverse(to, from);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 17:20:07

LeetCode—— Binary Tree Traversal的相关文章

[leetcode]Binary Tree Zigzag Level Order Traversal

Binary Tree Zigzag Level Order Traversal Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example:Given binary tree {3,9,20,#

[leetcode]Binary Tree Level Order Traversal @ Python

原题地址:http://oj.leetcode.com/problems/binary-tree-level-order-traversal/ 题意:二叉树的层序遍历的实现. 解题思路:二叉树的层序遍历可以用bfs或者dfs来实现.这里使用的dfs实现,代码比较简洁.实际上,二叉树的先序遍历就是dfs实现.   比如一棵树如下: 1 /  \ 2       3 /    \    /   \ 4     5  6    7    二叉树的先序遍历为{1,2,4,5,3,6,7},可以看到这个遍

[LeetCode] Binary Tree Zigzag Level Order Traversal(bfs)

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 return its zig

[leetcode]Binary Tree Zigzag Level Order Traversal @ Python

原题地址:http://oj.leetcode.com/problems/binary-tree-zigzag-level-order-traversal/ 题意: Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between

[leetcode]Binary Tree Level Order Traversal II @ Python

原题地址:http://oj.leetcode.com/problems/binary-tree-level-order-traversal-ii/ 题意: Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). For example:Given binary

[LeetCode] Binary Tree Zigzag Level Order Traversal 二叉树的之字形层序遍历

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example:Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 return its zigz

LeetCode &quot;Binary Tree *-order Traversal&#39; by Iteration

Binary Tree *-order traversal by recursion is trivial. But their iteration version deserves a look: Pre-Order class Solution { vector<int> ret; public: vector<int> preorderTraversal(TreeNode *p) { if (!p) return ret; stack<TreeNode *> st

leetcode - Binary Tree Preorder Traversal &amp;&amp; Binary Tree Inorder Traversal &amp;&amp; Binary Tree Postorder Traversal

简单来说,就是二叉树的前序.中序.后序遍历,包括了递归和非递归的方法 前序遍历(注释中的为递归版本): 1 #include <vector> 2 #include <stack> 3 #include <stddef.h> 4 #include <iostream> 5 6 using namespace std; 7 8 struct TreeNode 9 { 10 int val; 11 TreeNode *left; 12 TreeNode *rig

Leetcode: Binary Tree Inorder Traversal(二叉树中序遍历)

题目: Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 2 / 3 return [1,3,2]. Note: Recursive solution is trivial, could you do it iteratively? 递归解法(C++): /** * Definition for binary tre