二叉樹的前序、中序、後序、層次遍歷的遞歸與非遞歸實現
阿新 • • 發佈:2017-06-24
不為 sta logs 結束 nod 遞歸實現 inorder count site
二叉樹的遍歷有前序遍歷、中序遍歷、後序遍歷、層次遍歷等,筆者在這裏總結一下各種遍歷的實現。
一.前序遍歷。
前序遍歷訪問節點順序為:根節點->左子節點->右子節點。
遞歸實現如下:
void preorder(TreeNode* root, vector<int>& nodes) { if (!root) return; nodes.push_back(root -> val); preorder(root -> left, nodes); preorder(root -> right, nodes); } vector<int> preorderTraversal(TreeNode* root) { vector<int> nodes; preorder(root, nodes); return nodes; }
非遞歸實現(使用棧)如下:
對於任一結點P:
①訪問結點P,並將結點P入棧;
②判斷結點P的左孩子是否為空,若為空,則取棧頂結點並進行出棧操作,並將棧頂結點的右孩子置為當前的結點P,循環至①;若不為空,則將P的左孩子置為當前的結點P;
③直到P為NULL並且棧為空,則遍歷結束。
vector<int> preorderTraversal(TreeNode *root) { vector<int> v; if (root == NULL) return v; stack<TreeNode*> s; TreeNode* temp = root; while (temp != NULL || !s.empty()) { while (temp != NULL) { v.push_back(temp->val); s.push(temp); temp = temp->left; } if (!s.empty()) { temp = s.top(); s.pop(); temp = temp->right; } } return v; }
二.中序遍歷。
中序遍歷訪問節點順序為:左子節點->根節點->右子節點。
遞歸實現如下:
void inorder(TreeNode* root, vector<int>& nodes) { if (!root) return; inorder(root -> left, nodes); nodes.push_back(root -> val); inorder(root -> right, nodes); } vector<int> inorderTraversal(TreeNode* root) { vector<int> nodes; inorder(root, nodes); return nodes; }
非遞歸實現(使用棧)如下:
對於任一結點P,
①若其左孩子不為空,則將P入棧並將P的左孩子置為當前的P,然後對當前結點P再進行相同的處理;
②若其左孩子為空,則取棧頂元素並進行出棧操作,訪問該棧頂結點,然後將當前的P置為棧頂結點的右孩子;
③直到P為NULL並且棧為空則遍歷結束
vector<int> inorderTraversal(TreeNode *root) { vector<int> v; if (root == NULL) return v; stack<TreeNode*> s; TreeNode *temp = root; while (temp != NULL || !s.empty()) { while (temp != NULL) { s.push(temp); temp = temp->left; } if (!s.empty()) { temp = s.top(); s.pop(); v.push_back(temp->val); temp = temp->right; } } return v; }
三.後序遍歷。
後序遍歷訪問節點順序為:左子節點->右子節點->根節點。
遞歸實現如下:
void postorder(TreeNode* root, vector<int>& nodes) { if (!root) return; postorder(root -> left, nodes); postorder(root -> right, nodes); nodes.push_back(root -> val); } vector<int> postorderTraversal(TreeNode* root) { vector<int> nodes; postorder(root, nodes); return nodes; }
非遞歸實現(使用棧)如下:
vector<int> postorderTraversal(TreeNode *root) { vector<int> v; stack<TreeNode*> s; TreeNode * curr = root; TreeNode * previsited = NULL; while (curr != NULL || !s.empty()) { while (curr != NULL) { s.push(curr); curr = curr->left; } curr = s.top(); // 當前節點的右孩子如果為空或者已經被訪問,則訪問當前節點 if (curr->right == NULL || curr->right == previsited) { v.push_back(curr->val); previsited = curr; s.pop(); curr = NULL; } else curr = curr->right; //否則訪問右孩子 } return v; }
四.層次遍歷。
使用隊列:
vector<vector<int>> levelOrder(TreeNode *root) { queue<TreeNode*> q; int count = 0; vector<int> v; vector<vector<int>> v2; if (root == NULL) return v2; q.push(root); count++; int count2 = 1; while (!q.empty()) { count = count2; count2 = 0; v.clear(); for (int i = 0; i < count; i++) { TreeNode * top = q.front(); v.push_back(top->val); if (top->left != NULL) { q.push(top->left); count2++; } if (top->right != NULL) { q.push(top->right); count2++; } q.pop(); } v2.push_back(v); } return v2; }
二叉樹的前序、中序、後序、層次遍歷的遞歸與非遞歸實現