二叉树遍历

二叉树遍历

前序

迭代

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
	
        stack<TreeNode*> stk;  //创建栈
		
        vector<int> ans;		//用来保存结果
		
        if(root == nullptr) return ans;		//如果root为空,直接返回空的ans
        stk.push(root);		//首先将root放入栈中
        TreeNode* node;		//用一个新的node指向root,作为迭代的指针,以保证root不变
		
		//主循环,只要栈stk不为空,就将当前top取出,
		//将top的右节点、左节点、依次放入栈中
        while(!stk.empty())
        {
            node = stk.top();
            stk.pop();
            ans.push_back(node->val);	//注意此时给ans赋值语句的位置,是在将头元素top踢掉之后,
            if(node->right!=nullptr) stk.push(node->right);
            if(node->left != nullptr) stk.push(node->left);
        }
        return ans;
    }
};

迭代2

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        stack<TreeNode*> stk;
		
        if(root == nullptr) return ans;
		
        TreeNode* cur = root;	//创建cur指向root,stack中先不放东西;
		
        while(cur || !stk.empty())  //可能会出现stack暂时为空的情况,但此时cur必定会有左或右节点
        {
			//如果此时cur为null,则为叶子节点下,
			//跳过while,cur指向stack中的top
			//此时cur代表的是每个子树的root节点
            while(cur != nullptr)
            {
                stk.push(cur);
                ans.push_back(cur->val);//注意此处ans赋值语句位置
                cur = cur->left;
            }
            cur = stk.top();
            stk.pop();
            cur = cur->right;
        }
        return ans;
    }
};

中序

迭代

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        if(root == nullptr) return ans;
        stack<TreeNode*> s;
        TreeNode* cur = root;
        while(cur || !s.empty())
        {
            while(cur!=nullptr)//因为是中序,所以先直接找到左末叶子
            {
                s.push(cur);
                cur = cur->left;
            }
			//依照前面的while找到的左叶子,栈中左叶子的前一个元素定是它的parent节点,
			//因此ans的给值为:
			//stack.top->val,pop掉,

            cur = s.top();
            s.pop();
            ans.push_back(cur->val); //注意此处ans赋值语句位置
			
            //,此时cur再指向左叶子的右节点(null),但是stack没有变
			//没关系,进入下一次循环后,cur会重新指向stack中的top,也就是
			//刚刚pop掉的那个节点的parent
			cur = cur->right;
			//在一个右节点入栈后,它的parent已经被pop掉了,因此可以实现左->中->右的顺序
        }
        return ans;
    }
};

后序

虚假的迭代

二叉树的后续: 左 右 中 等于是 使用前序方法得到 中 右 左 再对结果进行逆序

//标*号的地方都是和前序遍历左右节点互换
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> ans;
        if(root == nullptr) return ans;
        stack<TreeNode*> s;
        TreeNode* cur = root;
        while(!s.empty() || cur)
        {
            while(cur)
            {
                s.push(cur);
                ans.push_back(cur->val);
                cur = cur->right; //******//
            }
            cur = s.top();
            s.pop();
            cur = cur->left;   //****//
        }
        reverse(ans.begin(),ans.end());
        return ans;
    }
};

真实的迭代

class Solution {
public:
    vector<int> postorderTraversal(TreeNode *root) {
        vector<int> res;
        if (root == nullptr) {
            return res;
        }

        stack<TreeNode *> stk;
        TreeNode *prev = nullptr;
        while (root != nullptr || !stk.empty()) {
            while (root != nullptr) {
                stk.emplace(root);
                root = root->left;
            }
            root = stk.top();
            stk.pop();
            if (root->right == nullptr || root->right == prev) {
                res.emplace_back(root->val);
                prev = root;
                root = nullptr;
            } else {
                stk.emplace(root);
                root = root->right;
            }
        }
        return res;
    }
};

递归

前序

class Solution {
public:
    void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == NULL) return;
        vec.push_back(cur->val);    // 中
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        traversal(root, result);
        return result;
    }
};

中序

        traversal(cur->left, vec);  // 左
        vec.push_back(cur->val);    // 中
        traversal(cur->right, vec); // 右

后序

        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
		vec.push_back(cur->val);    // 中
posted @ 2020-11-13 13:53  wztuuu  阅读(77)  评论(0)    收藏  举报