1.二叉树遍历
先序:父、左、右
中序:左、父、右
后序:左、右、父
常用思路是递归转迭代(倒序压栈)
压入根节点
取出栈顶结点
按照遍历顺序倒序压入三个节点(父、左、右)
压入根节点时额外压入一个空节点
读到空节点时取出该节点并删除
直到栈空
先(根-左-右):
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> call;
if(root!=nullptr) call.push(root);//根入栈(要考虑测试数据为空的情况)
while(!call.empty()){
TreeNode *t = call.top();
call.pop();
if(t!=nullptr){
if(t->right) call.push(t->right);//右
if(t->left) call.push(t->left);//左
call.push(t);//根
call.push(nullptr);
}else{
res.push_back(call.top()->val);
call.pop();
}
}
return res;
}
中:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> call;
if(root!=nullptr) call.push(root);//根入栈(要考虑测试数据为空的情况)
while(!call.empty()){
TreeNode *t = call.top();
call.pop();
if(t!=nullptr){
if(t->right) call.push(t->right);//右
call.push(t);//根
call.push(nullptr);
if(t->left) call.push(t->left);//左
}else{
res.push_back(call.top()->val);
call.pop();
}
}
return res;
}
后:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> call;
if(root!=nullptr) call.push(root);//根入栈(要考虑测试数据为空的情况)
while(!call.empty()){
TreeNode *t = call.top();
call.pop();
if(t!=nullptr){
call.push(t);//根
call.push(nullptr);
if(t->right) call.push(t->right);//右
if(t->left) call.push(t->left);//左
}else{
res.push_back(call.top()->val);
call.pop();
}
}
return res;
}
2.二叉树展开为链表
如题:
展开的顺序为先序遍历,用一个指针pre来存放上一个遍历的结点,初始为null,用倒序(6-5-4-3-2-1)访问,每次使pre成为当前节点的右节点并释放掉左节点(因为是先序遍历的倒序右-左-根,左节点一定已经访问过了),更新pre。
void flatten(TreeNode* root) {
stack<TreeNode*> call;
TreeNode* pre = nullptr;
if(root!=nullptr) call.push(root);
while(!call.empty()){
TreeNode *t = call.top();
call.pop();
if(t!=nullptr){
call.push(t);//根
call.push(nullptr);
if(t->left) call.push(t->left);//左
if(t->right) call.push(t->right);//右
}else{
if(pre!=nullptr){
call.top()->right=pre;
pre->left=nullptr;
}
pre=call.top();
call.pop();
}
}
if(pre!=nullptr) pre->left=nullptr;
}