二叉树遍历
在一棵树中,顶点p是顶点v的父亲,则它们的高度的关系是height(v) < height(p)
今天的内容主要有二叉树节点BinNode的建立,二叉树的前,中,层次遍历. 主要参照邓俊辉老师的讲解.
BinNode
我这里用到的是结构体,其他也可以.
struct BinNode
{
T data;
BinNode<T>* parent;
BinNode<T>* lc;//左孩子
BinNode<T>* rc;//右孩子
int height;
//构造函数
BinNode():parent(NULL),lc(NULL),rc(NULL),height(0){}
BinNode(T _data,BinNode<T>* _parent):data(_data),parent(_parent){}
//把e当作当前节点的左孩子插入(默认左孩子为空)
BinNode<T>* InsAslc(T const& e);
//把e当作当前节点的右孩子插入(默认you孩子为空)
BinNode<T>* InsAsrc(T const& e);
void preOrder(BinNode<T>* x);
void inOrder(BinNode<T>* x);
void levelOrder(BinNode<T>* x);
};
//把e当作当前节点的左孩子插入(默认左孩子为空)
template<typename T>
BinNode<T>* BinNode<T>::InsAslc(T const& e)
{
return this.lc= new BinNode(e,this);
}
//把e当作当前节点的右孩子插入(默认you孩子为空)
template<typename T>
BinNode<T>* BinNode<T>::InsAsrc(T const& e)
{
return this.rc= new BinNode(e,this);
}
先序遍历
//先序遍历
//递归实现
template<typename T>
void BinTree<T>::preOrder(BinNode<T>* x)
{
if(!x)
return 0;
cout<<x->data;
preOrder(x->lc);
preOrder(x->rc);
}
下面的是迭代实现
void BinTree<T>::preOrder(BinNode<T>*x)
{
stack<BinNode<T>*> s;
if(x)
s.push(x);
while(!s.empty())
{
BinNode* z= s.top();
s.pop();
cout<<z->data;
if(z->rc)s.push(z->rc);
if(z->lc)s.push(z->lc);
}
}
中序遍历
//中序遍历
template<typename T>
void BinTree<T>::inOrder(BinNode<T>* x)
{
if(!x)
return 0;
inOrder(x->lc);
cout<<x->data;
inOrder(x->rc);
}
下面的是迭代实现
void BinTree<T>::inOrder(BinNode<T>* x)
{
stack<BinNode<T>*> s;
while(!s.empty()||x)
{
while(x)
{
s.push(x);
x= x->lc;
}
while(!s.empty())
{
x= s.top;
s.pop();
cout<<x->data;
if(x->rc)
x= x->rc;
}
}
}
层次遍历
template <typename T>
void BinTree<T>::levelOrder(BinNode<T>* x)
{
queue<BinNode<T>* > q;
q.push(x);
while(!q.empty())
{
BinNode<T>* z= q.front();
q.pop();
cout<<z->data;
if(z->lc)
q.push(z->lc);
if(z->rc)
q.push(z->rc);
}
}
遍历其实不难理解,尤其是递归算法。下面谈谈我对非递归,也就是迭代算法的认识。
以先序遍历为例,我们知道,先序遍历就是VLR的流程,所以第一个visit的必定是根节点;而又因为是非递归的方法,所以我们需要借助其他的数据结构来存储节点:这里主要有栈(LIFO)和队列(FIFO)。
区别如下
图画的乱糟糟但确实有助于我理解,不懂的可以自己画画。
最后呢是用栈来存储选定了存储结构,接下来的事就比较简单了。首先把便利的根节点存入栈中,然后while判空为真就停止,while里取出栈顶元素,visit一下,然后pop。!!!!!接下来要把子女节点也加到栈中,因为栈的LIFO原则,所以先让右孩子进,然后是左孩子,如是循环即可。
本文来自博客园,作者:klaus08,转载请注明原文链接:https://www.cnblogs.com/klaus08/p/15105047.html