二叉树的遍历:
(traversing binary tree
traversing binary tree)是指从根节点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。
二叉树的遍历方法:(从左到右)
- 前序遍历
- 中序遍历
- 后序遍历
- 层序遍历
前序遍历
前序遍历二叉树的操作定义:
若二叉树为空,则空操作:否则:
(1)访问根结点
(2)先序遍历左子树
(3)先序遍历右子树
如下图,遍历的顺序为:ABCDEFGHI
对前序遍历做一个分析:
- 先访问A结点,结果为A
- 接下来访问A结点的左子树,显示字母为B,结果为AB
- 现在访问B的左子树,显示为D,结果为ABD
- 接着访问D的左子树,显示为H,结果为ABDH
- 现在访问H的左子树,因为H没有左子树,所以访问右子树,显示为K,结果为ABDHK
- 遍历到K之后访问它的左子树,因为K没有左右子树,就返回到上一级H,也执行完毕,返回到D结点,无右子树执行完毕,返回到B,找到了B结点的右子树,显示为E,结果为ABDHKE
- 因为E没有左右子树,所以返回到上一层到结点A,现在访问A结点的右子树C,结果为ABDHKEC
- 现在遍历C结点的左子树,显示为F,结果为ABDHKECF
- F有个左子树I,结果为ABDHKEECFI
- I无左右子树,返回上一层到结点F,结点F无右子树,返回上一层都结点C,找到结点G,结果为ABDHKECFIG
- 因为G无左子树,所以遍历出G结点的右子树,结果为ABDHKECFIGJ
中序遍历:
中序遍历二叉树的操作定义:
规则是若树为空,则空操作返回,否则:
(1)从根结点开始(注意并不是先访问根结点)
(2)中序遍历根结点的左子树,然后是访问根结点
(3)最后中序遍历右子树
如下图,遍历的顺序为:GDHBAEICF
对中序遍历做一个分析:
- 根节点A存在左子树,先中序遍历以节点B为根节点的左子树
- 节点B存在左子树,中序遍历以节点D为根节点的左子树
- 节点H不存在左子树,存在右子树,结果为KH
- 节点D无右子树,结果为KHD
- 节点B存在右子树,遵循从左到右的顺序,结果为KHDBE
- 中序遍历到A节点,结果为KHDBEA
- 节点A有右子树节点C,先中序遍历节点C为根节点的左子树
- 节点F存在左子树,中序遍历以节点F为根节点的左子树
- 节点I不存在左右子树,结果为HKDBEAI
- 节点F不存在右子树,结果为HKDBEAIF
- 节点C存在右子树,结果为HKDBEAIFCG
- 最后的结果为HKDBEAIFCGJ
后序遍历
后序遍历二叉树的操作定义:
规则是若树为空,则空操作返回,否则:
(1)从左到右先叶子后结点的方式遍历访问左右子树
(2)最后是访问根结点
如下图,遍历的顺序为:GHDBIEFCA
对后序遍历做一个分析
- 根节点A有左子树,后序遍历以节点B为根节点的左子树
- 按照上面那个方法,可以得到由根节点A->B->D->H
- 节点H无左子树,在查看H的右子树K,因为节点K无左右子树,结果为KHDEB
- A根节点的左子树完成,现在访问右子树,结果为KHDEBIFJGC
- 最后结果为KHDEBIFJGCA
层序遍历
中序遍历二叉树的操作定义:
规则是若树为空,则空操作返回
(1)否则从树的第一层,也就是根结点开始访问
(2)从上而下逐层遍历
(3)在同一层中,按从左到右的顺序对结点逐个访问。
如下图,遍历的顺序为:ABCDEFGHI
对层序遍历分析:
- 第一层A,结果为A
- 第二层B,C 结果为ABC
- 第三层DEFG,结果为ABCEDEFG
- 第四层HIJ,结果ABCEDEFGHIJ
- 第五层K,结果为ABCEDEFGHIJK
代码实现:
前序遍历:
递归:
void preOrder()
{
preOrder(_root);
cout << endl;
}
void preOrder(BSTNode* node)
{
if (node != nullptr)
{
cout << node->_data << " ";
preOrder(node->_left);
preOrder(node->_right);
}
}
非递归:
void nonpreOrder()
{
if (_root == nullptr)
{
return;
}
stack <BSTNode*> stack;
stack.push(_root);
while (!stack.empty())
{
BSTNode* top = stack.top();
cout << top->_data << " ";
stack.pop();
if (top->_right != nullptr)
{
stack.push(top->_right);
}
if (top->_left != nullptr)
{
stack.push(top->_left);
}
}
cout << endl;
}
中序遍历:
递归:
void inOrder()
{
inOrder(_root);
cout << endl;
}
void inOrder(BSTNode* node)
{
if (node != nullptr)
{
inOrder(node->_left);
cout << node->_data << " ";
inOrder(node->_right);
}
}
非递归:
void noninOrder()
{
if (_root == nullptr)
{
return;
}
stack<BSTNode*> stack;
BSTNode* top = _root;
while (!stack.empty() || top != nullptr)
{
if (top != nullptr)
{
stack.push(top);
top = top->_left;
}
else
{
top = stack.top();
cout << top->_data << " ";
stack.pop();
top = top->_right;
}
}
cout << endl;
}
后序遍历:
递归:
void lastOrder()
{
lastOrder(_root);
cout << endl;
}
void lastOrder(BSTNode* node)
{
if (node != nullptr)
{
lastOrder(node->_left);
lastOrder(node->_right);
cout << node->_data << " ";
}
}
非递归:
void nonlastOrder()
{
if (_root == nullptr)
{
return;
}
stack<BSTNode*> Stack;
stack<BSTNode*> StackRes;
BSTNode* top = _root;
Stack.push(top);
while (!Stack.empty())
{
top = Stack.top();
StackRes.push(top);
Stack.pop();
if (top->_left != nullptr)
{
Stack.push(top->_left);
}
if (top->_right != nullptr)
{
Stack.push(top->_right);
}
}
while (!StackRes.empty())
{
top = StackRes.top();
cout << top->_data << " ";
StackRes.pop();
}
cout << endl;
}
层序遍历:
递归:
void levelOrder()
{
int level = Treelevel(); // 求层数
for (int i = 0; i < level; ++i)
{
levelOrder(_root, i);
}
}
void levelOrder(BSTNode* node, int level)
{
if (node == nullptr)
{
return;
}
if (level == 0)
{
cout << node->_data << " ";
}
else
{
levelOrder(node->_left, level - 1);
levelOrder(node->_right, level - 1);
}
}
int Treelevel(BSTNode* node)
{
if (node == nullptr)
{
return 0;
}
int left = Treelevel(node->_left);
int right = Treelevel(node->_right);
return (left > right ? left : right) + 1;
}
非递归:
void nonlevelOrder()
{
queue<BSTNode *> Nodequeue;
if (_root == nullptr)
{
return;
}
Nodequeue.push(_root);
while (!Nodequeue.empty())
{
BSTNode* front = Nodequeue.front();
if (front->_left != nullptr)
{
Nodequeue.push(front->_left);
}
if (front->_right != nullptr)
{
Nodequeue.push(front->_right);
}
cout << front->_data << " ";
Nodequeue.pop();
}
cout << endl;
}