数据结构开发(24):二叉树中属性操作、层次遍历与典型遍历

0.目录

1.二叉树中属性操作的实现

2.二叉树结构的层次遍历

3.二叉树的典型遍历方式

4.小结

1.二叉树中属性操作的实现

二叉树的属性操作:

二叉树中结点的数目:

  • 定义功能:count(node)

    1. 在 node 为根结点的二叉树中统计结点数目

在BTree.h中实现统计结点数目:

protected:
    int count(BTreeNode<T>* node) const
    {
        int ret = 0;

        if( node != NULL )
        {
            ret = count(node->left) + count(node->right) + 1;
        }

        return ret;
    }
public:
    int count() const
    {
        return count(root());
    }

优化代码:

protected:
    int count(BTreeNode<T>* node) const
    {
        return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0;
    }
public:
    int count() const
    {
        return count(root());
    }

二叉树的高度:

  • 定义功能:height(node)

    1. 获取 node 为根结点的二叉树的高度

在BTree.h中实现获取二叉树的高度:

protected:
    int height(BTreeNode<T>* node) const
    {
        int ret = 0;

        if( node != NULL )
        {
            int lh = height(node->left);
            int rh = height(node->right);

            ret = ((lh > rh) ? lh : rh) + 1;
        }

        return ret;
    }
public:
    int height() const
    {
        return height(root());
    }

树的度数:

  • 定义功能:degree(node)

    1. 获取 node 为根结点的二叉树的度数

在BTree.h中实现获取二叉树的度数:

protected:
    int degree(BTreeNode<T>* node) const
    {
        int ret = 0;

        if( node != NULL )
        {
            int dl = degree(node->left);
            int dr = degree(node->right);

            ret = (!!node->left + !!node->right);

            if( ret < dl )
            {
                ret = dl;
            }

            if( ret < dr )
            {
                ret = dr;
            }
        }

        return ret;
    }
public:
    int degree() const
    {
        return degree(root());
    }

优化代码:

protected:
    int degree(BTreeNode<T>* node) const
    {
        int ret = 0;

        if( node != NULL )
        {
            BTreeNode<T>* child[] = { node->left, node->right };

            ret = (!!node->left + !!node->right);

            for(int i=0; (i<2) && (ret<2); i++)
            {
                int d = degree(child[i]);

                if( ret < d )
                {
                    ret = d;
                }
            }
        }

        return ret;
    }
public:
    int degree() const
    {
        return degree(root());
    }

统一mian.cpp测试:

#include <iostream>
#include "BTree.h"

using namespace std;
using namespace StLib;

int main()
{
    BTree<int> bt;
    BTreeNode<int>* n = NULL;

    bt.insert(1, NULL);

    n = bt.find(1);
    bt.insert(2, n);
    bt.insert(3, n);

    n = bt.find(2);
    bt.insert(4, n);
    bt.insert(5, n);

    n = bt.find(4);
    bt.insert(8, n);
    bt.insert(9, n);

    n = bt.find(5);
    bt.insert(10, n);

    n = bt.find(3);
    bt.insert(6, n);
    bt.insert(7, n);

    cout << bt.count() << endl;
    cout << bt.height() << endl;
    cout << bt.degree() << endl;

    return 0;
}

运行结果为:

10
4
2

2.二叉树结构的层次遍历

二叉树的遍历:

  • 二叉树的遍历 ( Traversing Binay Tree ) 是指从根结点出发,按照某种次序依次访问二叉树中的所有结点,使得每个结点被访问一次,且仅被访问一次。

需要考虑的问题:

  • 通用树结构的层次遍历算法是否可以用在二叉树结构上?
  • 如果可以,代码需要做怎样的改动

设计思路 ( 游标 ):

  • 提供一组遍历相关的函数,按层次访问二叉树中的数据元素。

层次遍历算法:

  • 原料:class LinkQueue
  • 游标:LinkQueue
  • 思想:
    1. begin() → 将根结点压入队列中
    2. current() → 访问队头元素指向的数据元素
    3. next() → 队头元素弹出,将队头元素的孩子压入队列中 ( 核心 )
    4. end() → 判断队列是否为空

层次遍历算法示例:

在BTree.h中实现二叉树结构的层次遍历:

(并且在clear()函数和remove()函数中要加上清空队列的操作。另外,将遍历操作的四个函数在父类中声明为虚函数。)

public:
    bool begin()
    {
        bool ret = (root() != NULL);

        if( ret )
        {
            m_queue.clear();
            m_queue.add(root());
        }

        return ret;
    }

    bool end()
    {
        return (m_queue.length() == 0);
    }

    bool next()
    {
        bool ret = (m_queue.length() > 0);

        if( ret )
        {
            BTreeNode<T>* node = m_queue.front();

            m_queue.remove();

            if( node->left != NULL )
            {
                m_queue.add(node->left);
            }

            if( node->right != NULL )
            {
                m_queue.add(node->right);
            }

        }

        return ret;
    }

    T current()
    {
        if( !end() )
        {
            return m_queue.front()->value;
        }
        else
        {
            THROW_EXCEPTION(InvalidOperationException, "No value at current position ...");
        }
    }

mian.cpp测试:

#include <iostream>
#include "BTree.h"

using namespace std;
using namespace StLib;

int main()
{
    BTree<int> bt;
    BTreeNode<int>* n = NULL;

    bt.insert(1, NULL);

    n = bt.find(1);
    bt.insert(2, n);
    bt.insert(3, n);

    n = bt.find(2);
    bt.insert(4, n);
    bt.insert(5, n);

    n = bt.find(4);
    bt.insert(8, n);
    bt.insert(9, n);

    n = bt.find(5);
    bt.insert(10, n);

    n = bt.find(3);
    bt.insert(6, n);
    bt.insert(7, n);

    for(bt.begin(); !bt.end(); bt.next())
    {
        cout << bt.current() << " ";
    }

    cout << endl;

    return 0;
}

运行结果为:

1 2 3 4 5 6 7 8 9 10 

3.二叉树的典型遍历方式

问题:

  • 二叉树是否只有一种遍历方式 ( 层次遍历 ) ?

典型的二叉树遍历方式:

  • 先序遍历 ( Pre-Order Traversal )
  • 中序遍历 ( In-Order Traversal )
  • 后序遍历 ( Post-Order Traversal )

先序遍历 ( Pre-Order Traversal ):

  • 二叉树为空:

    1. 无操作,直接返回
  • 二叉树不为空:
    1. 访问根结点中的数据元素
    2. 先序遍历左子树
    3. 先序遍历右子树

先序遍历功能定义:

中序遍历 ( In-Order Traversal ):

  • 二叉树为空:

    1. 无操作,直接返回
  • 二叉树不为空:
    1. 中序遍历左子树
    2. 访问根结点中的数据元素
    3. 中序遍历右子树

中序遍历功能定义:

后序遍历 ( Post-Order Traversal ):

  • 二叉树为空:

    1. 无操作,直接返回
  • 二叉树不为空:
    1. 后序遍历左子树
    2. 后序遍历右子树
    3. 访问根结点中的数据元素

后序遍历功能定义:

需要考虑的问题:

  • 是否可以将二叉树的典型遍历算法集成到 BTree 中?
  • 如果可以,代码需要做怎样的改动?

设计要点:

  • 不能与层次遍历函数冲突,必须设计新的函数接口
  • 算法执行完成后,能够方便的获得遍历结果
  • 遍历结果能够反映结点访问的先后次序

函数接口设计

  • SharedPointer< Array<T> > traversal(BTTraversal order)

    1. 根据参数 order 选择执行遍历算法 ( 先序,中序,后序 )
    2. 返回值为堆中的数组对象 ( 生命期由智能指针管理 )
    3. 数组元素的次序反映遍历的先后次序

典型遍历示例:

二叉树的典型遍历方式:

#include "LinkQueue.h"
#include "DynamicArray.h"
namespace StLib
{

enum BTTraversal
{
    PreOrder,
    InOrder,
    PostOrder
};

template <typename T>
class BTree : public Tree<T>
{
protected:
    void preOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
    {
        if( node != NULL )
        {
            queue.add(node);
            preOrderTraversal(node->left, queue);
            preOrderTraversal(node->right, queue);
        }
    }

    void inOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
    {
        if( node != NULL )
        {
            inOrderTraversal(node->left, queue);
            queue.add(node);
            inOrderTraversal(node->right, queue);
        }
    }

    void postOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
    {
        if( node != NULL )
        {
            postOrderTraversal(node->left, queue);
            postOrderTraversal(node->right, queue);
            queue.add(node);
        }
    }
public:
    SharedPointer< Array<T> > traversal(BTTraversal order)
    {
        DynamicArray<T>* ret = NULL;
        LinkQueue<BTreeNode<T>*> queue;

        switch (order) {
        case PreOrder:
            preOrderTraversal(root(), queue);
            break;
        case InOrder:
            inOrderTraversal(root(), queue);
            break;
        case PostOrder:
            postOrderTraversal(root(), queue);
            break;
        default:
            THROW_EXCEPTION(InvalidParameterException, "Parameter order is invalid ...");
            break;
        }

        ret = new DynamicArray<T>(queue.length());

        if( ret != NULL )
        {
            for(int i=0; i<ret->length(); i++, queue.remove())
            {
                ret->set(i, queue.front()->value);
            }
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create return array ...");
        }

        return ret;
    }
};

}

main.cpp测试:

#include <iostream>
#include "BTree.h"

using namespace std;
using namespace StLib;

int main()
{
    BTree<int> bt;
    BTreeNode<int>* n = NULL;

    bt.insert(1, NULL);

    n = bt.find(1);
    bt.insert(2, n);
    bt.insert(3, n);

    n = bt.find(2);
    bt.insert(4, n);
    bt.insert(5, n);

    n = bt.find(4);
    bt.insert(8, n);
    bt.insert(9, n);

    n = bt.find(5);
    bt.insert(10, n);

    n = bt.find(3);
    bt.insert(6, n);
    bt.insert(7, n);

    cout << bt.count() << endl;
    cout << bt.height() << endl;
    cout << bt.degree() << endl;

    cout << "层次遍历:" << endl;
    for(bt.begin(); !bt.end(); bt.next())
    {
        cout << bt.current() << " ";
    }
    cout << endl;

    SharedPointer< Array<int> > sp = NULL;

    sp = bt.traversal(PreOrder);

    cout << "先序遍历:" << endl;
    for(int i=0; i<(*sp).length(); i++)
    {
        cout << (*sp)[i] << " ";
    }
    cout << endl;

    sp = bt.traversal(InOrder);

    cout << "中序遍历:" << endl;
    for(int i=0; i<(*sp).length(); i++)
    {
        cout << (*sp)[i] << " ";
    }
    cout << endl;

    sp = bt.traversal(PostOrder);

    cout << "后序遍历:" << endl;
    for(int i=0; i<(*sp).length(); i++)
    {
        cout << (*sp)[i] << " ";
    }
    cout << endl;

    return 0;
}

运行结果为:

10
4
2
层次遍历:
1 2 3 4 5 6 7 8 9 10
先序遍历:
1 2 4 8 9 5 10 3 6 7
中序遍历:
8 4 9 2 10 5 1 6 3 7
后序遍历:
8 9 4 10 5 2 6 7 3 1 

4.小结

  • 二叉树的典型遍历都是以递归方式执行的
  • BTree 以不同的函数接口支持典型遍历
  • 层次遍历与典型遍历互不冲突
  • 遍历结果能够反映树结点访问的先后次序

最终的BTree.h代码:

BTree.h

#ifndef BTREE_H
#define BTREE_H

#include "Tree.h"
#include "BTreeNode.h"
#include "Exception.h"
#include "LinkQueue.h"
#include "DynamicArray.h"

namespace StLib
{

enum BTTraversal
{
    PreOrder,
    InOrder,
    PostOrder
};

template <typename T>
class BTree : public Tree<T>
{
protected:
    LinkQueue<BTreeNode<T>*> m_queue;

    virtual BTreeNode<T>* find(BTreeNode<T>* node, const T& value) const
    {
        BTreeNode<T>* ret = NULL;

        if( node != NULL )
        {
            if( node->value == value )
            {
                return node;
            }
            else
            {
                if( ret == NULL )
                {
                    ret = find(node->left, value);
                }

                if( ret == NULL )
                {
                    ret = find(node->right, value);
                }
            }
        }

        return ret;
    }

    virtual BTreeNode<T>* find(BTreeNode<T>* node, BTreeNode<T>* obj) const
    {
        BTreeNode<T>* ret = NULL;

        if( node == obj )
        {
            return node;
        }
        else
        {
            if( node != NULL )
            {
                if( ret == NULL )
                {
                    ret = find(node->left, obj);
                }

                if( ret == NULL )
                {
                    ret = find(node->right, obj);
                }
            }
        }

        return ret;
    }

    virtual bool insert(BTreeNode<T>* n, BTreeNode<T>* np, BTNodePos pos)
    {
        bool ret = true;

        if( pos == ANY )
        {
            if( np->left == NULL )
            {
                np->left = n;
            }
            else if( np->right == NULL )
            {
                np->right = n;
            }
            else
            {
                ret = false;
            }
        }
        else if( pos == LEFT )
        {
            if( np->left == NULL )
            {
                np->left = n;
            }
            else
            {
                ret = false;
            }
        }
        else if( pos == RIGHT )
        {
            if( np->right == NULL )
            {
                np->right = n;
            }
            else
            {
                ret = false;
            }
        }
        else
        {
            ret = false;
        }

        return ret;
    }

    virtual void remove(BTreeNode<T>* node, BTree<T>*& ret)
    {
        ret = new BTree<T>();

        if( ret == NULL )
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create new tree ...");
        }
        else
        {
            if( root() == node )
            {
                this->m_root = NULL;
            }
            else
            {
                BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent);

                if( parent->left == node )
                {
                    parent->left = NULL;
                }
                else if( parent->right == node )
                {
                    parent->right = NULL;
                }

                node->parent = NULL;
            }

            ret->m_root = node;
        }
    }

    virtual void free(BTreeNode<T>* node)
    {
        if( node != NULL )
        {
            free(node->left);
            free(node->right);

            if( node->flag() )
            {
                delete node;
            }
        }
    }

    int count(BTreeNode<T>* node) const
    {
        return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0;
    }

    int height(BTreeNode<T>* node) const
    {
        int ret = 0;

        if( node != NULL )
        {
            int lh = height(node->left);
            int rh = height(node->right);

            ret = ((lh > rh) ? lh : rh) + 1;
        }

        return ret;
    }

    int degree(BTreeNode<T>* node) const
    {
        int ret = 0;

        if( node != NULL )
        {
            BTreeNode<T>* child[] = { node->left, node->right };

            ret = (!!node->left + !!node->right);

            for(int i=0; (i<2) && (ret<2); i++)
            {
                int d = degree(child[i]);

                if( ret < d )
                {
                    ret = d;
                }
            }
        }

        return ret;
    }

    void preOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
    {
        if( node != NULL )
        {
            queue.add(node);
            preOrderTraversal(node->left, queue);
            preOrderTraversal(node->right, queue);
        }
    }

    void inOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
    {
        if( node != NULL )
        {
            inOrderTraversal(node->left, queue);
            queue.add(node);
            inOrderTraversal(node->right, queue);
        }
    }

    void postOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
    {
        if( node != NULL )
        {
            postOrderTraversal(node->left, queue);
            postOrderTraversal(node->right, queue);
            queue.add(node);
        }
    }
public:
    bool insert(TreeNode<T>* node)
    {
        return insert(node, ANY);
    }

    virtual bool insert(TreeNode<T>* node, BTNodePos pos)
    {
        bool ret = true;

        if( node != NULL )
        {
            if( this->m_root == NULL )
            {
                node->parent = NULL;
                this->m_root = node;
            }
            else
            {
                BTreeNode<T>* np = find(node->parent);

                if( np != NULL )
                {
                    ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos);
                }
                else
                {
                    THROW_EXCEPTION(InvalidParameterException, "Invalid parent tree node ...");
                }
            }
        }
        else
        {
            THROW_EXCEPTION(InvalidParameterException, "Parameter node can not be NULL ...");
        }

        return ret;
    }

    bool insert(const T& value, TreeNode<T>* parent)
    {
        return insert(value, parent, ANY);
    }

    virtual bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos)
    {
        bool ret = true;
        BTreeNode<T>* node = BTreeNode<T>::NewNode();

        if( node == NULL )
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create new node ...");
        }
        else
        {
            node->value = value;
            node->parent = parent;

            ret = insert(node, pos);

            if( !ret )
            {
                delete node;
            }
        }

        return ret;
    }

    SharedPointer< Tree<T> > remove(const T& value)
    {
        BTree<T>* ret = NULL;
        BTreeNode<T>* node = find(value);

        if( node == NULL )
        {
            THROW_EXCEPTION(InvalidParameterException, "Can not find the tree node via value ...");
        }
        else
        {
            remove(node, ret);

            m_queue.clear();
        }

        return ret;
    }

    SharedPointer< Tree<T> > remove(TreeNode<T>* node)
    {
        BTree<T>* ret = NULL;

        node = find(node);

        if( node == NULL )
        {
            THROW_EXCEPTION(InvalidParameterException, "Parameter node is invalid ...");
        }
        else
        {
            remove(dynamic_cast<BTreeNode<T>*>(node), ret);

            m_queue.clear();
        }

        return ret;
    }

    BTreeNode<T>* find(const T& value) const
    {
        return find(root(), value);
    }

    BTreeNode<T>* find(TreeNode<T>* node) const
    {
        return find(root(), dynamic_cast<BTreeNode<T>*>(node));
    }

    BTreeNode<T>* root() const
    {
        return dynamic_cast<BTreeNode<T>*>(this->m_root);
    }

    int degree() const
    {
        return degree(root());
    }

    int count() const
    {
        return count(root());
    }

    int height() const
    {
        return height(root());
    }

    void clear()
    {
        free(root());

        m_queue.clear();

        this->m_root = NULL;
    }

    bool begin()
    {
        bool ret = (root() != NULL);

        if( ret )
        {
            m_queue.clear();
            m_queue.add(root());
        }

        return ret;
    }

    bool end()
    {
        return (m_queue.length() == 0);
    }

    bool next()
    {
        bool ret = (m_queue.length() > 0);

        if( ret )
        {
            BTreeNode<T>* node = m_queue.front();

            m_queue.remove();

            if( node->left != NULL )
            {
                m_queue.add(node->left);
            }

            if( node->right != NULL )
            {
                m_queue.add(node->right);
            }

        }

        return ret;
    }

    T current()
    {
        if( !end() )
        {
            return m_queue.front()->value;
        }
        else
        {
            THROW_EXCEPTION(InvalidOperationException, "No value at current position ...");
        }
    }

    SharedPointer< Array<T> > traversal(BTTraversal order)
    {
        DynamicArray<T>* ret = NULL;
        LinkQueue<BTreeNode<T>*> queue;

        switch (order) {
        case PreOrder:
            preOrderTraversal(root(), queue);
            break;
        case InOrder:
            inOrderTraversal(root(), queue);
            break;
        case PostOrder:
            postOrderTraversal(root(), queue);
            break;
        default:
            THROW_EXCEPTION(InvalidParameterException, "Parameter order is invalid ...");
            break;
        }

        ret = new DynamicArray<T>(queue.length());

        if( ret != NULL )
        {
            for(int i=0; i<ret->length(); i++, queue.remove())
            {
                ret->set(i, queue.front()->value);
            }
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create return array ...");
        }

        return ret;
    }

    ~BTree()
    {
        clear();
    }
};

}

#endif // BTREE_H

原文地址:https://www.cnblogs.com/PyLearn/p/10164169.html

时间: 2024-10-07 08:35:57

数据结构开发(24):二叉树中属性操作、层次遍历与典型遍历的相关文章

数据结构开发(25):二叉树中属性操作、层次遍历与典型遍历

0.目录 1.二叉树的比较与相加 2.二叉树的线索化实现 3.二叉树的经典面试题分析 3.1 单度结点删除 3.2 中序线索化二叉树 4.小结 1.二叉树的比较与相加 二叉树的克隆操作: SharedPointer< BTree<T> > clone() const 克隆当前树的一份拷贝 返回值为堆空间中的一棵新二叉树 ( 与当前树相等 ) 二叉树的克隆: 定义功能:clone(node) 拷贝 node 为根结点的二叉树 ( 数据元素在对应位置相等 ) 在BTree.h中实现二叉

数据结构开发(21):树中属性操作与层次遍历

0.目录 1.树中属性操作的实现 2.树形结构的层次遍历 3.小结 1.树中属性操作的实现 树中结点的数目: 定义功能:count(node) 在 node 为根结点的树中统计结点数目 树结点数目的计算示例: count(A) = count(B) + count(C) + count(D) + 1 在GTree.h中实现统计结点数目: protected: int count(GTreeNode<T>* node) const { int ret = 0; if( node != NULL

第六十五课 二叉树中属性操作的实现

递归功能函数: 1 int count(BTreeNode<T>* node) const 2 { 3 return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0; 4 } 功能函数如下: 1 int height(BTreeNode<T>* node) const 2 { 3 int ret = 0; 4 5 if( node != NULL ) 6 { 7 int lh = hei

1 数据结构(13)_二叉树的概念及常用操作实现

1. 树到二叉树的转换 思考:通用树结构的实现太过复杂(树中每个结点都可以有任意多的孩子,具有多种形态),工程中很少会用到如此复杂的树是否可以简化呢?思路:减少树结点中孩子的数量.但这样树是否还能通用呢? 1.1.树的两种表示法 双亲孩子表示法:孩子兄弟表示法:孩子兄弟表示法的特点:1.能够表示任意的树形结构2.每个结点包含一个数据成员和两个指针成员3.孩子结点指针和兄弟结点指针构成"树杈" 2.2.二叉树 二叉树是由n(n>=0)个节点组成的有限集合,该集合或者为空,或者是由一

数据结构开发(23):二叉树中结点的查找、插入、删除与清除操作

0.目录 1.二叉树中结点的查找操作 2.二叉树中结点的插入操作 3.二叉树中结点的删除操作 4.二叉树中结点的清除操作 5.小结 1.二叉树中结点的查找操作 查找的方式: 基于数据元素值的查找 BTreeNode<T>* find(const T& value) const 基于结点的查找 BTreeNode<T>* find(TreeNode<T>* node) const 树中数据元素和结点的查找: 基于数据元素值的查找: 定义功能:find(node,

二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)

将二叉树相关的操作集中在一个实例里,有助于理解有关二叉树的相关操作: 1.定义树的结构体: 1 typedef struct TreeNode{ 2 int data; 3 struct TreeNode *left; 4 struct TreeNode *right; 5 }TreeNode; 2.创建根节点: 1 TreeNode *creatRoot(){ 2 TreeNode * root =(TreeNode *)malloc(sizeof(TreeNode)); 3 if(NULL=

递归非递归的二叉树遍历(递归前中后,非递归前中后,层次遍历,凹入打印法等)

由于所有的递归算法都可以借助于堆栈转换成循环结构的非递归算法.方法一:形式化模拟转换.方法二:根据要求解问题的特点设计借助于堆栈的循环结构算法.而此次正好是利用第二种按方法求解. 1.1非递归前序遍历: 首先利用下图来设计非递归前序遍历算法思想: 堆栈结构体如下: #define size 100 typedef struct { DataType data[size]; int tag[100]; //这个是在非递归后序中用到 int top : }SeqStack : (1)初始化设置一个堆

二叉树的前中后序递归和非递归遍历操作【代码】

“遍历”是二叉树各种操作的基础,可以在遍历过程中对节点进行各种操作,如:求节点的双亲,求节点的孩子,判断节点的层次,当然,还有一些更重要的操作,例如,依据遍历序列建立二叉树,,再如,对建立的二叉树进行线索化,等等. 二叉树的各种遍历操作必须了然于心,无论是递归的,还是非递归的.递归算法的优点是形式简单,当然,正如一句话所说“迭代是人,递归是神.”递归算法的整个详细过程还是很烧脑的,每一步都把未知当作已知,每一步又在把未知变为已知.想不到描述起来又用上了递归的概念,生活中其实有很多递归的现象,我印

二叉树的前中后以及层次遍历

#include "stdio.h" #include "malloc.h" #define datatype char  typedef struct bT { datatypedata; struct bT *lt,*rt; }* bitree,BiNode; void preExCreate(bitree bt); /*递归实现*/ void FprePost(bitree bt) { if(bt) { printf("%c",bt->