1.二叉树基础
(1)定义:有且仅有一个根节点,除根节点以外,每个节点只有一个父节点,最多有两个子节点,子节点有左右之分。
(2)存储结构:二叉树的存储结构可以采用顺序存储结构,也可以采用链式存储结构,其中链式存储更加灵活。
在链式存储中,二叉树的每个节点采用结构体表示,结构体包含三个域:数据域、左指针域、右指针域。
2.二叉树遍历
“遍历”是二叉树各种操作的基础,二叉树是一种非线性结构,遍历就是要让树的所有节点被且被访问一次,即按一定规律排列成一个线性队列。二叉树的遍历方式可以分为下面四种,分别为:“前序遍历”、“中序遍历”、“后序遍历”、“层序遍历”。下面依次介绍这几种遍历方式:
(1)前序遍历
若二叉树为空,则直接返回。否则先访问根节点,然后前序遍历左子树,再前序遍历右子树。如下图所示:
代码如下:
//递归实现:
void PrevOrder()
{
_PrevOrder(_root);
cout<<endl;
}
void _PrevOrder(Node* root)
{
if(root == NULL)
return;
cout<<root->_data<<" ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
//非递归实现:
void PrevOrderNoR()
{
stack<Node*> s;
Node* cur = _root;
while(cur || !s.empty())
{
while(cur)
{
cout<<cur->_data<<" ";
s.push(cur);
cur = cur->_left;
}
//走到这儿,最左路节点已经访问
Node* top = s.top();
s.pop();
cur = top->_right;
}
}
(2)中序遍历
若二叉树为空,则直接返回。否则从根节点开始(注意不是先访问根节点),中序遍历根节点的左子树,然后是访问根节点,最后中序遍历右子树。如下图所示:
代码如下:
//递归实现:
void InOrder()
{
_InOrder(_root);
cout<<ednl;
}
void _InOrder(Node* root)
{
if(root == NULL)
return;
_InOrder(root->_left);
cout<<root->_data<<" ";
_InOrder(root->_right);
}
//非递归实现:
void InOrderNoR()
{
stack<Node*> s;
Node* cur = _root;
while(cur || !s.empty())
{top
while(cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
cout<<top->_data<<" ";
s.pop();
cur = top->_right;
}
}
(3)后序遍历
若二叉树为空,则直接返回。否则从左到右先叶子后结点的方式遍历访问左右子树,最后访问根节点。如下图所示:
代码如下:
//递归如下:
void PostOrder()
{
_PostOrder(_root);
cout<<endl;
}
void _PostOrder(Node* root)
{
if(root == NULL)
return ;
_PostOrder(root->_left);
_PostOrder(root->_right);
cout<<root->_data<<" ";
}
//非递归如下:
PostOrderNoR()
{
stack<Node*> s;
Node* prev = NULL;
Node* cur = _root;
while(cur || !s.empty())
{
while(cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
if(top->_right == NULL || top->_right == prev)
{
cout<<top->_data<<" ";
prev = top;
s.pop();
}
else
{
cur = top->_right;
}
}
}
(4)层序遍历
层序遍历,顾名思义就是一层一层的遍历,习惯上我们都是每一层按照从左往右的顺序去遍历。代码如下:
//层序遍历的非递归实现:
void LevelOrder()
{
queue<Node*> q;
if(_root)
q.push(_root);
while(!q.empty())
{
Node* front = q.front();
cout<<front->_data<<" ";
if(front->_left)
{
q.push(front->_left);
}
if(front->_right)
{
q.push(front->_right);
}
q.pop();
}
}
好啦,二叉树的遍历就是这么简单~~~