LeetCode—— Binary Tree Traversal
来源:互联网 发布:js浏览器定位 编辑:程序博客网 时间:2024/06/07 02:34
二叉树遍历的三道题
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 Traversalclass Solution {public:vector<int> postorderTraversal(TreeNode *root) { vector<int> result; /* p,正在访问的结点,q,刚刚访问过的结点 */ const TreeNode *p, *q; stack<const TreeNode *> s; 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);}
0 0
- LeetCode——Binary Tree Preorder Traversal
- LeetCode——Binary Tree Postorder Traversal
- LeetCode——Binary Tree Inorder Traversal
- LeetCode——Binary Tree Preorder Traversal
- LeetCode——Binary Tree Inorder Traversal
- LeetCode——Binary Tree Preorder Traversal
- LeetCode—— Binary Tree Traversal
- Binary Tree Preorder Traversal —— Leetcode
- Binary Tree Postorder Traversal—LeetCode
- LeetCode Binary Tree Traversal
- LeetCode | Binary Tree Traversal
- 【leetcode】Binary Tree Traversal
- Leetcode - Tree - Binary Tree Traversal
- leetcode——94——Binary Tree Inorder Traversal
- leetcode——144——Binary Tree Preorder Traversal
- leetcode——145——Binary Tree Postorder Traversal
- LeetCode——Binary Tree Level Order Traversal
- LeetCode——Binary Tree Level Order Traversal II
- 小断大端问题
- Android 人脸特征点检测(主动形状模型) ASM Demo (Active Shape Model on Android)
- hdu 4741——Save Labman No.004
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- window.location.href后面的url带多个参数
- LeetCode—— Binary Tree Traversal
- voltDB探索工具
- Java设计模式(一) 之 详解单例模式
- Codeforces Round #280 (Div. 2) D. Vanya and Computer Game 数学+预处理
- Android INSTALL_FAILED_UID_CHANGED
- ATL/COM----IDL和MIDL之详解
- iphone的系统信息使用[UIDevice currentDevice]
- hdu5305Friends dfs
- mysql进阶(四)mysql中select