#include <iostream>
#include <vector>
#include <stack>
using namespace std;
//Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
/*
在144先序的基础上用栈和morris实现
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode *> mystack;
vector<int> myvec;
if (root == NULL) {
return myvec;
}
TreeNode *cur = root;
while (!mystack.empty() || cur) {
//所有节点都有可能成为根,
if (cur) {
mystack.push(cur);
cur = cur->left;
} else { //当左子树是空的就看右子树,同时访问根节点
cur = mystack.top();
mystack.pop();
myvec.push_back(cur->val);
cur = cur->right;
}
}
return myvec;
}
};
/*
morris遍历,只用一个指针遍历即可不用栈,空间为O(1),时间为O(N),
将一颗左子树的最右的节点,指向它的根。在遍历右子树。如果没有左子树
就直接遍历cur,然后访问它的右子树;如果有左子树,就遍历这个节点,然后
访问左子树,并在左子树中寻找以这个节点为根的最后一个叶子节点,并将利用
第一种情况的特点将叶子节点的右儿子连着根,当访问完最后一个节点再访问根
的右子树。重要的是找跟的过程,前序和中序的区别就是前序一找到跟就push进去,
中序要便利完跟的左子树才能将根push。
*/
//class Solution {
//public:
// vector<int> preorderTraversal(TreeNode* root) {
// vector<int> myvec;
// TreeNode *cur = root;
// while (cur) {
// if (cur->left == NULL) {
// myvec.push_back(cur->val);
// cur = cur->right;
// } else {
// //寻找根的过程
// TreeNode *prev = cur->left;
// while (prev->right && prev->right != cur) {
// prev = prev->right;
// }
// if (prev->right == NULL) {
// //寻找到根的位置
// //myvec.push_back(cur->val);
// //建立线索后,遍历左子树
// prev->right = cur;
// cur = cur->left;
// } else {
// /*去掉线索,恢复树的结构,
// cur的左子树已全部遍历过了,
// 遍历右子树
// */
// //左子树之后是根
// myvec.push_back(cur->val);
// prev->right = NULL;
// cur = cur->right;
// }
// }
// }
// return myvec;
// }
//};
int main(int argc, const char * argv[]) {
TreeNode one = TreeNode(1);
TreeNode two = TreeNode(2);
TreeNode three = TreeNode(3);
one.right = &two;
two.left = &three;
Solution s;
vector<int> result = s.preorderTraversal(&one);
for (int i = 0; i < result.size(); i++) {
cout << result[i] << " ";
}
cout << endl;
return 0;
}
leetcode-94-Binary Tree Inorder Traversal
最新推荐文章于 2021-12-24 23:39:21 发布