Loading

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;
            }
        }
    }
}
posted @ 2022-05-04 20:57  青芒果冻  阅读(128)  评论(0)    收藏  举报