二叉树的遍历
- 前序遍历:
遍历顺序:根节点,左子树,右子树
递归遍历:访问根节点,递归调用再访问左子树,右子树
//前序遍历
void PrevOrder()
{
_PrevOrder(_root);
cout << endl;
}
void _PrevOrder(Node* root)
{
if (root == NULL)
{
return;
}
cout << root->_data << " ";//根节点
_PrevOrder(root->_leftNode);//左子树
_PrevOrder(root->_rightNode);//右子树
}
非递归遍历:压入根节点的左子树节点并访问,取栈顶元素,对其右子树节点进行压栈(右子树节点作为子树的根节点说不定会有左子树节点)。
//前序遍历
void PrevOrder_NonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
cout << cur->_data << " ";
s.push(cur);
cur = cur->_leftNode;
}
Node* top = s.top();
cur = top->_rightNode;
s.pop();
}
cout << endl;
}
- 中序遍历
遍历顺序:左子树,根节点,右子树
递归遍历:递归调用左子树并访问,根节点,再右子树
//中序遍历
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void _InOrder(Node* root)
{
if (root == NULL)
{
return;
}
_InOrder(root->_leftNode);//左子树
cout << root->_data << " ";//根节点
_InOrder(root->_rightNode);//右子树
}
非递归遍历:
和前序遍历一样,建立栈将根节点的左子树节点压入,但不访问。在取栈顶元素的时候对节点进行访问。
//中序遍历
void InOrder_NonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
//压入根节点的左子树节点
while (cur)
{
s.push(cur);
cur = cur->_leftNode;
}
//取栈顶元素并进行访问
Node* top = s.top();
cout << top->_data << " ";
s.pop();
//对右子树节点进行遍历
cur = top->_rightNode;
}
cout << endl;
}
- 后序遍历
遍历顺序:左子树,右子树,根节点
递归遍历:
//后序遍历
void PostOrder()
{
_PostOrder(_root);
cout << endl;
}
void _PostOrder(Node* root)
{
if (root == NULL)
{
return;
}
_PostOrder(root->_leftNode);//左子树
_PostOrder(root->_rightNode);//右子树
cout << root->_data << " ";//根节点
}
非递归遍历:
左子树节点遍历后不能对直接取栈顶元素进行pop操作,需要对其右子树节点进行判断,这里需要记录上次访问的节点prevNode,右子树节点为空或右子树节点为上次访问过的节点,都说明此子树已经遍历完成。
//后序遍历
void PostOrder_NonR()
{
Node* cur = _root;
Node* prevNode = NULL;//记录上次访问的节点
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_leftNode;
}
Node* top = s.top();
if (top->_rightNode == NULL || top->_rightNode == prevNode)
{
cout << top->_data << " ";
s.pop();
prevNode = top;
}
else
{
cur = top->_rightNode;
}
}
cout << endl;
}
- 层序遍历
- 利用队列先进先出的特点,将根节点压进队列,如果此根节点存在左子树节点和右子树节点,就将根节点先出队列,再将左子树节点和右子树节点进队列;
- 此次进入的左右子树节点也会作为根节点有其对应的左右子树节点,再进行根节点出队列,左右子树节点进队列操作即可,直至所有节点全被遍历。
//层序遍历
void LevelOrder()
{
queue<Node*> q;
if (_root)
{
q.push(_root);
}
while (!q.empty())
{
Node* front = q.front();
cout << front->_data << " ";
q.pop();
if (front->_leftNode)
{
q.push(front->_leftNode);
}
if (front->_rightNode)
{
q.push(front->_rightNode);
}
}
cout << endl;
}