二叉树

Binary Tree Link

二叉树的一些性质

//二叉树的性质
//性质一:二叉树的第 i 层, 最多有2的 i - 1 次方个节点 (i >= 1)
//性质二: 高度为 k 的二叉树至多有 (2 的k 次方) - 1 个节点 ( k >= 1)
//性质三: 二叉树的总数量等于节点的总度数 + 1
//性质四: 任何一个二叉树,若叶子节点数量为 n0 ,度为 2 的节点数量为 n2, 则叶子节点的数量比有
            //两个子树的节点数量多一个,即: n0 = n2 + 1 

        //若假设度为1的节点数量为n1,   那么二叉树节点总数量:   n = n0 + n1 + n2;
        //节点总度数 = 2 * n2 + n1;
        //根据性质3,节点的总数量 n = 2 * n2 + n1 + 1
        // n0 + n1 + n2 = 2 * n2 + n1 + 1 ==>     n0 = n2 + 1

    
        //知道了一个完全二叉树的节点总数 n,  如何求出n0 (叶子节点数量),n1(度为一的数量),n2(度为二的数量)
            //a) 完全二叉树最多只有一个度为 1 的节点, 即 n1 = 0, 或者 n1 = 1;
            //b) 根据公式 n = 2 * n2 + n1 + 1,其中 2 * n2+ 1 的结果肯定是奇数(不能被2整除的整数)
            //c) 如果该完全二叉树节点总数是偶数(能被2整除),那么 n1必定是奇数,也就是 值 1
            //   如果完全二叉树节点总数是奇数,那么 n1 必定是偶数也就是值 0


//层序遍历 / 层次遍历 (也称为 广度优先遍历 / 广度优先搜索),一般要借助队列。
//从根节点开始,从上到下,从左到右
//层序遍历的过程
    //a)初始化一个队列
    //b)把二叉树的根节点入队列
    //c)判断队列是否为空,如果不为空,就让队头节点出队(相当于遍历了该节点),同时将这个刚刚出队列的左孩子和右孩子分别入队列
            //如果该节点有左右孩子
    //d)重复 c) 步骤,一直到队列为空。

//二叉树的存储结构:顺序,链式
    //顺序的存储方式:用一段连续的内存单元(数组)一次从上到下从左到右存储二叉树各个节点元素.
    //存储的是完全二叉树。 根在数组下标为 i = 1。那么左字节点就存储在 2 * i 的位置,右子节点就存储在 2 * i + 1 = 3 的位置。

    //链式存储方式:适用于普通的二叉树
    //节点结构:一个数据域,两个指针域

节点标记与节点定义

enum ECCHILDSIGN            //节点标记,CreateNode()的时候需要使用
{
    E_Root,                 //树根
    E_ChildLeft,            //左孩子
    E_ChildRight            //右孩子
};

//树中每个节点的定义
template<typename T>                   //T代表数据元素的类型
struct BinaryTreeNode
{
    T               data;              //数据域
    BinaryTreeNode* LeftChild;         //左子节点指针
    BinaryTreeNode* RightChild;        //右子节点定义
};

 

二叉树的定义

//二叉树的定义
template<typename T>
class BinaryTree
{
public:
    BinaryTree();
    ~BinaryTree();
public:
    //创建一个树节点
    BinaryTreeNode<T>* CreateNode(BinaryTreeNode<T>* parentnode, ECCHILDSIGN pointSign, const T& e);
    //利用扩展二叉树的前序遍历序列来创建一颗二叉树
    void CreateBTreeAccorPT(char* pstr);
private:
    //利用扩展二叉树的前序遍历序列创建二叉树的递归函数
    void CreateBTreeAccorPTRecu(BinaryTreeNode<T>*& tnode, char*& pstr);   //参数类型为应用,确保递归函数调用中对参数的改变会影响到调用者
    void RleaseNode(BinaryTreeNode<T>* pnode);                             //释放树节点
public:
    //遍历操作
    void preOrder();        //前序遍历
    void inOrder();         //中序遍历
    void postOrder();       //后序遍历

private:
    void preOrder(const BinaryTreeNode<T>* tNode);
    void inOrder(const BinaryTreeNode<T>* tNode);
    void postOrder(const BinaryTreeNode<T>* tNode);

public:
    void levelOrder();      //层序遍历二叉树

private:
    void levelOrder(BinaryTreeNode<T>* tNode);

public:
    int getSize();        //求二叉树节点个数
    int getHeight();      //求二叉树高度
    BinaryTreeNode<T>* SearchElem(const T& e);                      //查找某个节点(假设二叉树节点各不相同)
    BinaryTreeNode<T>* GetParent(BinaryTreeNode<T>* tSonNode);      //查找某个节点的父节点
    void CopyTree(BinaryTree<T>* targetTree);                       //树的拷贝
    void prePrder_noRecu();                                         //非递归方式前序遍历二叉树
    void inOrder_noRecu();                                          //非递归方式中序遍历二叉树
    void postOrder_noRecu();                                        //非递归后续遍历二叉树
    //如何跟根据前序、中序遍历序列来创建一颗二叉树
    //参数pP_t:前序遍历序列, 比如 "ABDCE", PI_T: 中序遍历序列,比如"DBACE"
    void CreateBTreeAccordPI(char* pP_T, char* pI_T);
    void CreateBTreeAccordIPO(char* p_IT, char* pPOST_T);           //如何根据中序(左根右)、后续遍历(左右根)序列来创建一颗二叉树
private:

    int getSize(BinaryTreeNode<T>* tNode);
    int getHeight(BinaryTreeNode<T>* tNode);
    BinaryTreeNode<T>* SearchElem(BinaryTreeNode<T>* pNode, const T& e);
    BinaryTreeNode<T>* GetParent(BinaryTreeNode<T>* tParNode, BinaryTreeNode<T>* tSonNode);     //tParNode是 tSonNode的爹节点
    void CopyTree(BinaryTreeNode<T>* tSource, BinaryTreeNode<T>*& tTarget);                     //注意第二个参数为引用
    void prePrder_noRecu(BinaryTreeNode<T>* tRoot);
    void inOrder_noRecu(BinaryTreeNode<T>* tRoot);
    void postOrder_noRecu(BinaryTreeNode<T>* tRoot);
    void CreateBTreeAccorPT(BinaryTreeNode<T>*& tnode, char* pP_T, char* pI_T, int n);
    void CreateBTreeAccordIPO(BinaryTreeNode<T>*& tnode, char* pI_T, char* pPOST_T, int n);

private:
    BinaryTreeNode<T>* root;         //树根节点
};

构造与析构

//构造函数的实现
template<typename T>
BinaryTree<T>::BinaryTree()
{
    root = nullptr;
}

//析构函数
template<typename T>
BinaryTree<T>::~BinaryTree()
{
    RleaseNode(root);
}

树节点的释放

//释放二叉树节点
template<typename T>
void BinaryTree<T>::RleaseNode(BinaryTreeNode<T>* pnode)
{
    if (pnode != nullptr)
    {
        RleaseNode(pnode->LeftChild);
        RleaseNode(pnode->RightChild);
    }
    delete pnode;
}

遍历操作

  • 前序遍历
template<typename T>
void BinaryTree<T>::preOrder()      //遍历操作,前序遍历
{
    preOrder(root);
}

template<typename T>
void BinaryTree<T>::preOrder(const BinaryTreeNode<T>* tNode)
{
    if (tNode != nullptr)   //若二叉树非空
    {
        //根左右顺序
        cout << (char)tNode->data << " ";   //输出节点的数据域值,用char显示字母
        preOrder(tNode->LeftChild);
        preOrder(tNode->RightChild);
    }
}
  • 中序遍历
template<typename T>
void BinaryTree<T>::inOrder()    //中序遍历
{
    inOrder(root);
}

template<typename T>
void BinaryTree<T>::inOrder(const BinaryTreeNode<T>* tNode)
{
    if (tNode != nullptr)   //若二叉树非空
    {
        //左根右顺序
        inOrder(tNode->LeftChild);
        cout << (char)tNode->data << " ";   //输出节点的数据域值,用char显示字母      
        inOrder(tNode->RightChild);
    }
}
  • 后续遍历
template<typename T>
void BinaryTree<T>::postOrder()    //后序遍历
{
    postOrder(root);
}

template<typename T>
void BinaryTree<T>::postOrder(const BinaryTreeNode<T>* tNode)
{
    if (tNode != nullptr)   //若二叉树非空
    {
        //左右根顺序
        postOrder(tNode->LeftChild);
        postOrder(tNode->RightChild);
        cout << (char)tNode->data << " ";   //输出节点的数据域值,用char显示字母 
    }
}
  • 层序遍历
template<typename T>
void BinaryTree<T>::levelOrder()       //层序遍历二叉树
{
    levelOrder(root);
}

template<typename T>
void BinaryTree<T>::levelOrder(BinaryTreeNode<T>* tNode)
{
    if (tNode != nullptr)    //二叉树非空
    {
        BinaryTreeNode<T>* tempnode;
        LinkQueue<BinaryTreeNode<T>* > lnobj;    //注意队列元素类型是节点指针类型

        lnobj.EnQueue(tNode);                   //先把根节点入队
        while (!lnobj.IsEmpty())                 //判断队列是否为空
        {
            lnobj.DeQueue(tempnode);            //出队列
            cout << (char)tempnode->data << " ";

            /*   可以在层序遍历中判断是否是完全二叉树
            //左子节点存在,而右子节点不存在,就不是一颗完全二叉树
            // if(tempnode->LeftChild == nullptr && tempnode->RightChild != nullptr)
            // {
            //    //这颗二叉树不是一颗完全二叉树
            //    cout << "不是完全二叉树" << endl;
            // }
            */
            if (tempnode->LeftChild != nullptr)
                lnobj.EnQueue(tempnode->LeftChild);
            if (tempnode->RightChild != nullptr)
                lnobj.EnQueue(tempnode->RightChild);
        }//end while
    }// end if 
}
  • 前序遍历(非递归)
template<typename T>
void BinaryTree<T>::prePrder_noRecu()                                  //非递归方式前序遍历二叉树
{
    prePrder_noRecu(root);
}

template<typename T>
void BinaryTree<T>::prePrder_noRecu(BinaryTreeNode<T>* tRoot)
{
    if (tRoot == nullptr)
    {
        return;
    }
    LinkStack<BinaryTreeNode<T>* > slinkobj;
    slinkobj.Push(tRoot);           //根节点入栈

    BinaryTreeNode<T>* tmpnode;
    while (!slinkobj.Empty())        //栈不空
    {
        slinkobj.Pop(tmpnode);      //栈顶元素出栈
        cout << (char)tmpnode->data << " ";   //访问栈顶元素
        if (tmpnode->RightChild != nullptr)    //注意先判断右树在判断左树
        {
            slinkobj.Push(tmpnode->RightChild);  //把右树入栈
        }

        if (tmpnode->LeftChild != nullptr)    //注意先判断右树在判断左树
        {
            slinkobj.Push(tmpnode->LeftChild);  //把左树入栈
        }

    }
}
  • 中序遍历(非递归)
template<typename T>
void BinaryTree<T>::inOrder_noRecu()                                       //非递归方式中序遍历二叉树
{
    inOrder_noRecu(root);
}

template<typename T>
void BinaryTree<T>::inOrder_noRecu(BinaryTreeNode<T>* tRoot)
{
    if (tRoot == nullptr)
    {
        return;
    }
    LinkStack<BinaryTreeNode<T>* > slinkobj;
    slinkobj.Push(tRoot);     //根节点入栈

    BinaryTreeNode<T>* tmpnode;
    while (!slinkobj.Empty())    //栈为空
    {
        while (tRoot->LeftChild != nullptr)
        {
            slinkobj.Push(tRoot->LeftChild);            //将左子节点入栈
            tRoot = tRoot->LeftChild;
        }//end while

        slinkobj.Pop(tmpnode);
        cout << (char)tmpnode->data << " ";

        //如果被访问的元素的右子节点不为空,则把其右子节点指定为当前节点入栈
        if (tmpnode->RightChild != nullptr)
        {
            tRoot = tmpnode->RightChild;        //将刚刚栈顶出栈的右节点设置为当前节点
            slinkobj.Push(tRoot);                //右节点入栈
        }

    }//end while
}
  • 后续遍历(非递归)
template<typename T>
void BinaryTree<T>::postOrder_noRecu()                         //非递归后续遍历二叉树
{
    postOrder_noRecu(root);
}

template<typename T>
void BinaryTree<T>::postOrder_noRecu(BinaryTreeNode<T>* tRoot)
{
    if (tRoot == nullptr)
        return;
    LinkStack<BTNode_extra<T> > slinkobj;
    BTNode_extra<T> ext_tmpnode;

    do
    {

        while (tRoot != nullptr)   //循环2
        {
            ext_tmpnode.point = tRoot;
            ext_tmpnode.pointSign = E_ChildLeft;    //标记先处理该节点的左孩子
            slinkobj.Push(ext_tmpnode);
            tRoot = tRoot->LeftChild;
        }//end while


        while (!slinkobj.Empty())  //循环3
        {
            slinkobj.Pop(ext_tmpnode);      //出栈
            if (ext_tmpnode.pointSign == E_ChildLeft)
            {
                ext_tmpnode.pointSign = E_ChildRight;   //标记该节点为右孩子
                slinkobj.Push(ext_tmpnode);             //重新入栈
                tRoot = ext_tmpnode.point->RightChild;
                break;                                  //终止while
            }
            else // if(ext_tmpnode.pointSign == E_RightChild)
            {
                cout << (char)ext_tmpnode.point->data << " ";
            }
        }//end while

    } while (!slinkobj.Empty());   //循环1

}

求节点个数

template<typename T>
int BinaryTree<T>::getSize()        //求二叉树节点个数
{
    return getSize(root);
}

template<typename T>
int BinaryTree<T>::getSize(BinaryTreeNode<T>* tNode)
{
    if (tNode == nullptr)
    {
        return 0;
    }
    return getSize(tNode->LeftChild) + getSize(tNode->RightChild) + 1;  //之所以 + 1,是因为有一个根节点
}

求二叉树高度

template<typename T>
int BinaryTree<T>::getHeight()      //求二叉树高度
{
    return getHeight(root);
}

template<typename T>
int BinaryTree<T>::getHeight(BinaryTreeNode<T>* tNode)
{
    if (tNode == nullptr)
    {
        return 0;
    }
    int lheight = getHeight(tNode->LeftChild);      //左子树高度
    int rheight = getHeight(tNode->RightChild);     //右子树高度
    if (lheight > rheight)
    {
        return lheight + 1;                         //之所以加一,是因为还包括根节点高度
    }
    else
    {
        return rheight + 1;                          //之所以加一,是因为还包括根节点
    }
}

查找某节点

template<typename T>
BinaryTreeNode<T>* BinaryTree<T>::SearchElem(const T& e)       //查找某个节点(假设二叉树节点各不相同)
{
    return SearchElem(root, e);
}

template<typename T>
BinaryTreeNode<T>* BinaryTree<T>::SearchElem(BinaryTreeNode<T>* pNode, const T& e)
{
    if (pNode == nullptr)
    {
        return nullptr;
    }
    if (pNode->data == e)    //从根开始找
    {
        return pNode;
    }

    BinaryTreeNode<T>* p = SearchElem(pNode->LeftChild, e);   //查找左孩子
    if (p != nullptr)     //这里判断不可缺少
        return p;
    return SearchElem(pNode->RightChild, e);                  //左子树查不到,继续到右子树查找,所以这里直接return

}

查找某节点的父节点

template<typename T>
BinaryTreeNode<T>* BinaryTree<T>::GetParent(BinaryTreeNode<T>* tSonNode)           //查找某个节点的父节点
{
    return GetParent(root, tSonNode);
}

template<typename T>
BinaryTreeNode<T>* BinaryTree<T>::GetParent(BinaryTreeNode<T>* tParNode, BinaryTreeNode<T>* tSonNode)//tParNode是 tSonNode的爹节点
{
    if (tParNode == nullptr || tSonNode == nullptr)
        return nullptr;
    if (tParNode->LeftChild == tSonNode || tParNode->RightChild == tSonNode)
    {
        return tParNode;
    }
    BinaryTreeNode<T>* p1 = GetParent(tParNode->LeftChild, tSonNode);                 //递归,在左边找
    if (p1 != nullptr)
    {
        return p1;
    }
    return GetParent(tParNode->RightChild, tSonNode);                               //递归,在右边找
}

树的拷贝

template<typename T>
void BinaryTree<T>::CopyTree(BinaryTree<T>* targetTree)             //树的拷贝
{
    CopyTree(root, targetTree->root);
}

template<typename T>
void BinaryTree<T>::CopyTree(BinaryTreeNode<T>* tSource, BinaryTreeNode<T>*& tTarget)    //注意第二个参数为引用
{
    if (tSource == nullptr)
    {
        tTarget = nullptr;
    }
    else
    {
        tTarget = new BinaryTreeNode<T>;
        tTarget->data = tSource->data;

        CopyTree(tSource->LeftChild, tTarget->LeftChild);               //对左子树进行拷贝
        CopyTree(tSource->RightChild, tTarget->RightChild);              //对右子树进行拷贝 
    }
}

树的创建

  • 使用节点标记的创建方式
//创建一个树节点
template<typename T>
BinaryTreeNode<T>* BinaryTree<T>::CreateNode(BinaryTreeNode<T>* parentnode, ECCHILDSIGN pointSign, const T& e)
{
    //将新节点创建迟来
    BinaryTreeNode<T>* tempnode = new BinaryTreeNode<T>;
    tempnode->data = e;
    tempnode->LeftChild = nullptr;
    tempnode->RightChild = nullptr;


    //把节点放入正确的位置
    if (pointSign == E_Root)
    {
        //创建的是根节点
        root = tempnode;
    }

    if (pointSign == E_ChildLeft)
    {
        //创建的是左孩子节点
        parentnode->LeftChild = tempnode;
    }
    else if (pointSign == E_ChildRight)
    {
        //创建的是右孩子节点
        parentnode->RightChild = tempnode;
    }

    return tempnode;
}
  • 扩展前序遍历创建方式
//利用扩展二叉树的前序遍历序列来创建一颗二叉树
template<typename T>
void BinaryTree<T>::CreateBTreeAccorPT(char* pstr)
{
    CreateBTreeAccorPTRecu(root, pstr);
}

//利用扩展二叉树的前序遍历序列创建二叉树的递归函数
template<typename T>
void BinaryTree<T>::CreateBTreeAccorPTRecu(BinaryTreeNode<T>*& tnode, char*& pstr)
{
    //ABD###C#E##
    if (*pstr == '#')
    {
        tnode = nullptr;
    }
    else
    {
        //根左右
        tnode = new BinaryTreeNode<T>;      //创建根节点
        tnode->data = *pstr;
        CreateBTreeAccorPTRecu(tnode->LeftChild, ++pstr);       //创建左子树
        CreateBTreeAccorPTRecu(tnode->RightChild, ++pstr);      //创建右子树
    }
}
  • 前序和中序遍历创建方式
//如何跟根据前序、中序遍历序列来创建一颗二叉树
//参数pP_t:前序遍历序列, 比如 "ABDCE", PI_T: 中序遍历序列,比如"DBACE"
template<typename T>
void BinaryTree<T>::CreateBTreeAccordPI(char* pP_T, char* pI_T)
{
    CreateBTreeAccorPT(root, pP_T, pI_T, strlen(pP_T));
}

//参数1为引用类型,确保递归调用中对参数的改变会影响到使用者。参数n:节点个数
template<typename T>
void BinaryTree<T>::CreateBTreeAccorPT(BinaryTreeNode<T>*& tnode, char* pP_T, char* pI_T, int n)
{
    if (n == 0)
    {
        tnode = nullptr;
    }
    else
    {
        //(1)在中序遍历序列中找根,前序遍历序列中根是在最前面
        int tmpindex = 0;   //下标
        while (pP_T[0] != pI_T[tmpindex])
            tmpindex++;

        tnode = new BinaryTreeNode<T>;                  //创建根节点
        tnode->data = pI_T[tmpindex];                   //第一次tmpindex ==  2

        //(2)创建左孩子
        CreateBTreeAccorPT(
            tnode->LeftChild,  //创建左孩子
            pP_T + 1,           //找到前序遍历序列中左树开始就节点的位置,这里跳过了第一个节点(根)A,得到 "BDCE"
            pI_T,               //中序遍历的节点不需要改动,仍旧是"DBACE"
            tmpindex
        );

        //(3)创建右孩子
        CreateBTreeAccorPT(
            tnode->RightChild,  //创建右孩子
            pP_T + tmpindex + 1,           //找到前序遍历序列中右树开始节点的位置,这里跳过了tmpindex + 1个节点(根)A,得到 "CE"
            pI_T + tmpindex + 1,               //找到中序遍历序列中右树开始节点的位置,得到的是 "CE"
            n - tmpindex - 1     //右孩子节点数                
        );

    }

}
  • 中序与后序遍历创建方式
template<typename T>
void BinaryTree<T>::CreateBTreeAccordIPO(char* p_IT, char* pPOST_T)    //如何根据中序(左根右)、后续遍历(左右根)序列来创建一颗二叉树
{
    CreateBTreeAccordIPO(root, p_IT, pPOST_T, strlen(pPOST_T));
}

template<typename T>
void BinaryTree<T>::CreateBTreeAccordIPO(BinaryTreeNode<T>*& tnode, char* pI_T, char* pPOST_T, int n)
{
    //可以通过后续遍历找到根节点
    if (n == 0)
    {
        tnode = nullptr;
    }
    else
    {
        //在中序遍历中找到根,后序遍历序列中根在最后
        int tmpindex = 0;     //下标
        while (pPOST_T[n - 1] != pI_T[tmpindex])
            ++tmpindex;

        tnode = new BinaryTreeNode<T>;          //创建根节点
        tnode->data = pI_T[tmpindex];

        //创建左孩子
        CreateBTreeAccordIPO(
            tnode->LeftChild,               //创建左孩子
            pI_T,                           //不需要改动,仍旧是 "DBACE",因为开头的都是左孩子
            pPOST_T,                        //不需要改动,仍旧是"DBECA"
            tmpindex                        //左孩子节点数
        );
        CreateBTreeAccordIPO(
            tnode->RightChild,              //创建右孩子
            pI_T + tmpindex + 1,            //找到中序遍历中右数开始的位置 "CE"
            pPOST_T + tmpindex,             //找到后序遍历中右树开始的位置,得到的是 "ECA"
            n - tmpindex - 1               //左孩子节点数
        );
    }
}

测试用例

int main()
{

    BinaryTree<int> tree;

    //创建一个二叉树
    BinaryTreeNode<int>* rootpoint = tree.CreateNode(nullptr, E_Root, 'A');   //创建树根节点
    BinaryTreeNode<int>* subpoint = tree.CreateNode(rootpoint, E_ChildLeft, 'B');    //创建左子节点B
    subpoint = tree.CreateNode(subpoint, E_ChildLeft, 'D');   //创建左子节点B下的左子节点D

    subpoint = tree.CreateNode(rootpoint, E_ChildRight, 'C');  //创建根的右子节点C
    subpoint = tree.CreateNode(subpoint, E_ChildRight, 'E');   //创建C的右子节点E

    //前序遍历序列: ABD###C#E##  (给出一个扩展二叉树的前序遍历序列,是能够唯一确定一颗二叉树的)
    BinaryTree<int> mytree;
    mytree.CreateBTreeAccorPT((char*)"ABD###C#E##");

    cout << "前序遍历序列为: ";
    mytree.preOrder();    //前序遍历
    cout << endl;

    cout << "中序遍历序列为: ";
    mytree.inOrder();     //中序遍历
    cout << endl;

    cout << "后序遍历序列为: ";
    mytree.postOrder();    //后续遍历
    cout << endl;

    cout << "层序遍历序列为: ";
    mytree.levelOrder();    //层序遍历
    cout << endl;

    cout << "二叉树节点个数为: " << mytree.getSize() << endl;
    cout << "二叉树的高度为: " << mytree.getHeight() << endl;

    //查找某个节点
    int val = 'B';
    BinaryTreeNode<int>* p = mytree.SearchElem(val);
    if (p != nullptr)
    {
        cout << "找到了值为 " << (char)val << " 的节点" << endl;
    }
    else
    {
        cout << "没找到找到值为 " << (char)val << " 的节点" << endl;
    }

    //查找某个节点的父节点
    BinaryTreeNode<int>* parp = mytree.GetParent(p);          //找到B的父节点
    if (parp != nullptr)
    {
        cout << "找到了值为 " << (char)val << " 节点的父节点" << (char)parp->data << endl;
    }
    else
    {
        cout << "没找到找到值为 " << (char)val << " 节点的父节点" << endl;
    }

    //测试树的拷贝
    cout << "树的拷贝: " << endl;
    BinaryTree<int> treecopy;
    tree.CopyTree(&treecopy);
    treecopy.levelOrder();
    cout << endl;

    cout << "非递归方式前序遍历序列为: ";
    mytree.prePrder_noRecu();
    cout << endl;

    cout << "非递归方式中序遍历序列为: ";
    mytree.inOrder_noRecu();
    cout << endl;

    cout << "非递归方式后序遍历序列为: ";
    mytree.postOrder_noRecu();
    cout << endl;

    cout << "使用前序遍历跟中序遍历创建一个二叉树: ";
    BinaryTree<int> mytree2;
    mytree2.CreateBTreeAccordPI((char*)"ABDCE", (char*)"DBACE");
    mytree2.levelOrder();
    cout << endl;

    cout << "使用中序遍历跟后序遍历创建一个二叉树: ";
    BinaryTree<int> mytree3;
    mytree3.CreateBTreeAccordIPO((char*)"DBACE", (char*)"DBECA");
    mytree3.levelOrder();
    cout << endl;
    return 0;
}

 注意事项

//!!!层序遍历使用到前面介绍的链式队列
//!!!非递归遍历使用了前面介绍的链式栈
//!!!使用g++编译的话,注意
  //#include "LinkStack.cc"
  //#include "LinkQueue.cc"
  //编译命令
    //g++ -o main binary_tree_link.cc LinkStack.cc LinkQueue.cc
    //上面main是可执行文件名称, binary_tree_link.cc 是本文介绍的文件名
posted @ 2022-08-02 22:40  huahuati  阅读(70)  评论(0)    收藏  举报