二叉樹深度優先遍歷詳解
阿新 • • 發佈:2018-12-25
二叉樹的遍歷(每一種遍歷次序有遞迴實現(簡捷)和迭代實現兩種方式)
深度優先遍歷
1.遞迴實現
中根遍歷的遞迴實現
vector<int> result; vector<int> inorderTraversal(TreeNode* root) { inorder(root); return result; } void inorder(TreeNode* root){ if(root == nullptr){ return; } inorder(root->left); result.push_back(root->val); inorder(root->right); }
其他順序的遍歷只需調換順序即可。
2.迭代實現
先根遍歷(先序遍歷)
例如下圖中左邊的單元,在先根遍歷中,列印1,然後進入以2為根節點的下一個單元,倘若2為NULL,那麼便進入3為根節點的下一個單元。
根節點→左子節點→右子節點,1,2,4,7,3,5,6,8
思路:迭代實現最重要的就是對路徑的儲存與回溯,如果不考慮上述內容,單單對每一次的迭代步驟進行實現,然後一路向下。
先根遍歷實現的程式碼為:
加入對路徑的記憶,將1到2的路徑記為第一路徑,將1到3的路徑記為第二路徑。將路徑的終點按照第一路徑在上,第二路徑在下的順序壓入棧中。If(cur!= NULL) cout << cur->val; If(cur->left != NUll)cur=cur->left Else cur = cur->right;
加入對路徑的記憶和提取
cur = s.top(); s.pop(); //從堆疊中提取路徑
cout << cur->val; //列印,列印後的路徑不用記憶
if(cur->right != NULL) s.push(cur->right);
if(cur->left != NULL) s.push(cur->left); //記憶路徑用於下一步的迭代
完整程式碼vector<int> preorderTraversal(TreeNode* root) { vector<int> result; stack< TreeNode *> s; TreeNode *cur; if(root != NULL){ s.push(root); } while(!s.empty()){ cur = s.top(); s.pop(); result.push_back(cur->val); if(cur->right != NULL) s.push(cur->right); if(cur->left != NULL) s.push(cur->left); } return result; }
中根遍歷(中序遍歷)
顧名思義,中根遍歷的根位於結果序列的中間
左子節點→根節點→右子節點,4,7,2,1,3,5,8,6
以下圖為例,在中根遍歷中,直接進入以2為根節點的單元,若2為空,列印1,進入以3為根節點的單元。
先根遍歷的基本邏輯實現為:
If(cur!= nullptr) cur = cur->left
Else cout << cur; cur = cur->right;
加入對於路徑的記憶和提取,只需要在進入左子節點之前記錄根節點即可。
If(cur != nullptr) {
S.push_back(cur);
cur = cur->left;
}else
{
cur = s.top();
s.pop();
result.push_back(cur->val);
cur = cur->right;
}
完整程式碼為vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<const TreeNode *> s;
const TreeNode *cur = root;
while(!s.empty() || cur != nullptr){
if(cur!= nullptr)
{
s.push(cur);
cur = cur->left;
}else
{
cur = s.top();
s.pop();
result.push_back(cur->val);
cur = cur->right;
}
}
return result;
}
後根遍歷(後序遍歷)
左子節點→右子節點→根節點
N、7、4、N、2、5、8、N、6、3、1
後根遍歷和先根遍歷的順序是完全相反的,所以可以依據先根遍歷的演算法,得到結果後,再將結果反轉過來即可。另外一種方法,太複雜,思路上屢不清,算了。
vector<int> postorderTraversal(TreeNode* root) {
vector<int> v;
if (!root) return v;
stack<TreeNode *> s;
s.push(root);
TreeNode *p = NULL;
while(!s.empty()) {
p = s.top();
s.pop();
v.insert(v.begin(), p->val);
if (p->left) s.push(p->left);
if (p->right) s.push(p->right);
}
return v;
}