1. 程式人生 > 實用技巧 >震驚!!為何伺服器為何頻頻被黑?小白苦不堪言

震驚!!為何伺服器為何頻頻被黑?小白苦不堪言

二叉樹遍歷

前序

迭代

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);    // 中