样例:
输入树的结构如下:
1
2 3
4 5
6前序遍历结果:
1, 2 ,4, 6, 3, 5
中序遍历结果:
4, 6, 2, 1, 3, 5
后序遍历结果:
6, 4, 2, 5, 3, 1
层次遍历结果:
1, 2, 3, 4, 5, 6
1. 前序遍历
按照根节点->左孩子->右孩子的访问顺序
递归版本
// 前序遍历递归版本 void PreOrder(TreeNode* pRoot) { if (pRoot != NULL) { cout << pRoot->val << " "; PreOrder(pRoot->left); PreOrder(pRoot->right); } }
非递归版本
// 前序遍历非递归版本 // 栈后进先出刚好符合前序遍历(根,左,右)特点,先push右孩子,在push左孩子 // 则打印过程先打印栈顶元素,然后再依次压入栈顶的右孩子,左孩子,依次循环 void PreOrderStack(TreeNode* pRoot) { if (pRoot != NULL) { stack<TreeNode*> temp; temp.push(pRoot); while (!temp.empty()) { TreeNode* node = temp.top(); cout << node->val << " "; // 打印栈顶元素的值 temp.pop(); if (node->right != NULL) // 有右孩子,先压入右孩子 temp.push(node->right); if (node->left != NULL) temp.push(node->left); } } }
2. 中序遍历
按照左孩子->根节点->右孩子的访问顺序
递归版本
// 中序遍历递归版本 void InOrder(TreeNode* pRoot) { if (pRoot != NULL) { InOrder(pRoot->left); cout << pRoot->val << " "; InOrder(pRoot->right); } }
非递归版本
// 中序遍历非递归版本 void InOrderStack(TreeNode* pRoot) { if (pRoot != NULL) { stack<TreeNode*> temp; TreeNode* node = pRoot; while (node!=NULL || !temp.empty()) //node!=NULL 保证第一次能进入循环 { if (node != NULL) // node 有值时,将该节点压入栈中 { temp.push(node); node = node->left; // node指向左孩子 } else // node 没有值时,已经到达叶子结点的孩子节点(NULL)或者没有左孩子的情况 { node = temp.top(); // 将node指向栈顶即叶子结点 cout << node->val << " "; temp.pop(); node = node->right; // node指向右孩子 } } } }
3. 后序遍历
按照左孩子->右孩子->根节点的访问顺序
递归版本
// 后序遍历递归版本 void LastOrder(TreeNode* pRoot) { if (pRoot != NULL) { LastOrder(pRoot->left); LastOrder(pRoot->right); cout << pRoot->val << " "; } }
非递归版本1
// 后序遍历非递归版本 void LastOrderStack1(TreeNode* pRoot) { if (pRoot == NULL) return; stack<TreeNode*> stack1, stack2; // 设计两个栈,栈1按根左右入栈,栈2每次迭代压入栈1栈顶元素 stack1.push(pRoot); // 由于栈后进先出的特点实际上栈2保存顺序为根->右子树->左子树 while (!stack1.empty()) { TreeNode* node = stack1.top(); stack2.push(node); stack1.pop(); if (node->left != NULL) stack1.push(node->left); if (node->right != NULL) stack1.push(node->right); } while (!stack2.empty()) // 栈2按出栈顺序打印则实现后序遍历 { int val = stack2.top()->val; cout << val << " "; stack2.pop(); } }
非递归版本2
void LastOrderStack2(TreeNode* pRoot) { if (pRoot == NULL) return; stack<TreeNode*> temp; TreeNode* node = pRoot; // node和栈temp共同控制迭代顺序 TreeNode* Last = NULL; while (node!=NULL || !temp.empty()) { if (node != NULL) // node有值时压入栈(优先压入左孩子) { temp.push(node); node = node->left; } else { TreeNode* top = temp.top(); // node为NULL时,以栈顶元素为判断条件 if (top->right != NULL&&Last != top->right) // 当栈顶元素有右孩子且不为上一次pop出的元素 { node = top->right; // node指向栈顶元素的右孩子 } else { cout << top->val << " "; temp.pop(); Last = top; // Last 记录上次pop元素,防止重复遍历 } } } }
4. 层次遍历
访问二叉树时,逐层访问,每层从左节点一直访问到右节点
// 广度优先遍历(层次遍历)
void LevelTraversal(TreeNode* pRoot)
{
if (pRoot == NULL)
return;
queue<TreeNode*> temp; // 采用队列控制迭代
temp.push(pRoot);
while (!temp.empty())
{
TreeNode* node = temp.front(); // 按根左右压入队列,由于队列先进先出的特点
cout << node->val << " ";
temp.pop(); // 弹出顺序即为层次遍历顺序
if (node->left != NULL)
temp.push(node->left);
if (node->right != NULL)
temp.push(node->right);
}
}