以下是使用递归实现中序遍历的算法:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> vec;
return traver(root, vec);
}
vector<int> traver(TreeNode* root, vector<int>& vec){
if(!root){
return vec;
}
traver(root->left, vec);
vec.push_back(root->val);
traver(root->right, vec);
return vec;
}
};
不使用递归的实现思路
算法1、2:
- 通过循环获取根节点root的左子点,得到以root为根节点的树中最左的节点,循环期间所有节点依次进栈直至“最左节点”进栈。
- 当"最左节点"进栈后,栈顶节点的值放进vector中,然后判断弹出栈顶节点并判断是否有右子节点,如果右子节点不为空,则以该右子节点为根节点执行1)
算法3 :
相较与1、2该算法更为巧妙简介
思路跟1、2大体相同,当在while循环体中,不需要每次都去获取栈顶节点,通过判断pCurrent是否为空对“左节点进栈”的同时也避免了重复遍历的情况。
1 使用栈去实现,但算法执行后树会发生改变
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> vector;
if(!root)
return vector;
stack<TreeNode *> stack;
stack.push(root);
while(!stack.empty())
{
TreeNode *pNode = stack.top();
if(pNode->left)
{
stack.push(pNode->left);
pNode->left = NULL;//放置重复遍历
}
else
{
vector.push_back(pNode->val);
stack.pop();
if(pNode->right)
stack.push(pNode->right);
}
}
return vector;
}
};
2 使用unordered_map和栈,算法执行后tree不会发生改变
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> vector;
if(!root)
return vector;
unordered_map<TreeNode *, bool> map;//left child has been visited:true.
stack<TreeNode *> stack;
stack.push(root);
while(!stack.empty())
{
TreeNode *pNode = stack.top();
if(pNode->left && !map[pNode])//防止重复遍历
{
stack.push(pNode->left);
map[pNode] = true;
}
else
{
vector.push_back(pNode->val);
stack.pop();
if(pNode->right)
stack.push(pNode->right);
}
}
return vector;
}
};
3 只使用一个栈但树的不会发生改变
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> vector;
stack<TreeNode *> stack;
TreeNode *pCurrent = root;
while(!stack.empty() || pCurrent)
{
if(pCurrent)
{
//同一根节点下的左右节点,左节点比右节点先出栈(即左节点后进栈,其实最后所有进栈的节点都可以视左一个树中的中间节点。)
stack.push(pCurrent);
pCurrent = pCurrent->left;//若左节点为空则,该节点可以等同为中间节点,相对于其右节点先出栈(后进栈)
}//节点为空就出栈
else
{//当节点出栈后,还需要判断是否有右子节点
TreeNode *pNode = stack.top();
vector.push_back(pNode->val);
stack.pop();
pCurrent = pNode->right;
}
}
return vector;
}
};