Mirrors 遍历
思想:构建一个在左子树遍历完之后能返回对应父节点的线索,相当于出发时就给自己的终点再买个回程票。
实质:建立一种机制,对于没有左子树的节点只到达一次,对于有左子树的节点会到达两次。
void mirrorsTraversal(TreeNode* root) {
TreeNode* cur = root; // 当前结点
TreeNode* pre = NULL; // cur的前驱节点(cur的左子树的最右结点)
while(cur != NULL) {
// cur没有左子树,直接访问该节点,再访问右子树
if(cur->left == NULL) {
cur = cur->right;
}
// cur有左子树,找前驱节点,判断是第一次访问还是第二次访问
else {
pre = c->left;
while(pre->right!=NULL && pre->right!=cur) {
pre = pre->right;
}
//是第一次访问,访问cur左子树
if(pre->right == NULL) {
pre->right = cur;
cur = cur->left;
}
//第二次访问,消除pre->right指针
//该节点访问完了,接下来应该访问其右子树
else {
pre->right = NULL;
cur = cur->right;
}
}
}
}
前序遍历
// 对于没有左子树的节点只到达一次,直接加入
// 对于有左子树的节点会到达两次,则在第一次到达时加入
vector<int> preorder(TreeNode* root) {
vector<int> res;
TreeNode* cur = root; // 当前结点
TreeNode* pre = NULL; // cur的前驱节点(cur的左子树的最右结点)
while(cur != NULL) {
// cur没有左子树,直接访问该节点,再访问右子树
if(cur->left == NULL) {
res.push_back(cur->val);
cur = cur->right;
}
// cur有左子树,找前驱节点,判断是第一次访问还是第二次访问
else {
pre = c->left;
while(pre->right!=NULL && pre->right!=cur) {
pre = pre->right;
}
//是第一次访问,访问cur左子树
if(pre->right == NULL) {
pre->right = cur;
res.push_back(cur->val);
cur = cur->left;
}
//第二次访问,消除pre->right指针
//该节点访问完了,接下来应该访问其右子树
else {
pre->right = NULL;
cur = cur->right;
}
}
}
}
中序遍历
// 对于没有左子树的节点只到达一次,直接加入
// 对于有左子树的节点会到达两次,则在第二次到达时加入
vector<int> inorder(TreeNode* root) {
vector<int> res;
TreeNode* cur = root; // 当前结点
TreeNode* pre = NULL; // cur的前驱节点(cur的左子树的最右结点)
while(cur != NULL) {
// cur没有左子树,直接访问该节点,再访问右子树
if(cur->left == NULL) {
res.push_back(cur->val);
cur = cur->right;
}
// cur有左子树,找前驱节点,判断是第一次访问还是第二次访问
else {
pre = c->left;
while(pre->right!=NULL && pre->right!=cur) {
pre = pre->right;
}
//是第一次访问,访问cur左子树
if(pre->right == NULL) {
pre->right = cur;
cur = cur->left;
}
//第二次访问,消除pre->right指针
//该节点访问完了,接下来应该访问其右子树
else {
pre->right = NULL;
res.push_back(cur->val);
cur = cur->right;
}
}
}
}

浙公网安备 33010602011771号