和我一起迎接明天的太阳吧

klaus08

焦虑源于行动的匮乏

二叉树遍历

在一棵树中,顶点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原则,所以先让右孩子进,然后是左孩子,如是循环即可。

posted @ 2020-02-07 15:09  klaus08  阅读(33)  评论(0编辑  收藏  举报