C++实现二叉树的基本操作

#include <iostream>
#include <stack>
#include <queue>
using std::cin;
using std::cout;
using std::endl;
using std::stack;
using std::queue;
typedef struct node
{
    int data;
    struct node *lchild;
    struct node *rchild;
}Bnode, *BTree;

//创建二叉树 例如输入 1 2 -1 -1 3 -1 -1 创建的是1 2 3二叉树
BTree CreateBinaryTree(BTree &tree)
{
    int inputdata;
    cin >> inputdata;
    if(-1 == inputdata)
    {
        tree = NULL;
    }
    else
    {
        if(!(tree = (Bnode*)malloc(sizeof(Bnode))))
        {
            cout << "ERROR";
        }
        tree->data = inputdata; //创建根结点
        tree->lchild = CreateBinaryTree(tree->lchild); //创建左子树 递归实现
        tree->rchild = CreateBinaryTree(tree->rchild); //创建右子树 递归实现
    }
    return tree;
}

//递归前序遍历
void preorderTraverse(BTree tree)
{
    if(tree != NULL)
    {
        cout << tree->data << " ";
        preorderTraverse(tree->lchild);
        preorderTraverse(tree->rchild);

    }
    else
    {
        //cout <<"二叉树为空" << endl;
        return;
    }
}

//非递归前序遍历
//先对根结点入栈,这样根结点最后出栈,保证了在其余层没有完全遍历时s.enpty()为假
//先访问根结点在访问左子树,直到左子树为空后返回其父结点,在访问其同级的右结点
void preorderNotRecursion(BTree tree)
{
    stack<BTree> s;
    if(!tree)
    {
        cout << "二叉树为空" << endl;
        return;
    }
    else
    {
        //借助栈的特性先进后出 实现最底层的到根的逐层输出
        while(tree || !s.empty())
        {
            while(tree)
            {
                s.push(tree);
                cout << tree->data << " ";
                tree = tree->lchild;
            }
            tree = s.top();
            s.pop();
            tree = tree->rchild;
        }
    }
}

//非递归中序遍历
void inorderNotRecursion(BTree tree)
{
    stack<BTree> s;
    if(!tree)
    {
        cout << "二叉树为空" << endl;
        return;
    }
    else
    {
        while(tree || !s.empty())
        {
            while(tree)
            {
                s.push(tree);
                tree = tree->lchild;
            }
            tree = s.top();
            cout << tree->data << " ";
            s.pop();
            tree = tree->rchild;
        }
    }
}

//递归中序遍历
void inorderTraverse(BTree tree)
{
    if(tree != NULL)
    {
        inorderTraverse(tree->lchild);
        cout << tree->data << " ";
        inorderTraverse(tree->rchild);
    }
    else
    {
        //cout <<"二叉树为空" << endl;
        return;
    }
}

//递归后序遍历
void postorderTraverse(BTree tree)
{
    if(tree != NULL)
    {
        postorderTraverse(tree->lchild);
        postorderTraverse(tree->rchild);
        cout << tree->data << " ";
    }
    else
    {
        return;
    }
}

//非递归后序遍历 画图可以加深印象 入栈出栈
void postorderNotRecursion(BTree tree)
{
    /*对于非递归的后序遍历,要保证根结点最后访问,这样对于任意一个结点p应先入栈
    如果p没有左子结点和右子结点或者其左子结点和右子结点均已经被访问过,则p结点可
    以直接访问,若非上述两种中情况则右子结点和左子结点依次入栈,保证每次出栈时左
    子结点在右子结点前被访问
    */
    stack<BTree> s;
    BTree cur;
    BTree pre = NULL;
    s.push(tree);
    if(!tree)
    {
        cout << "二叉树为空" << endl;
        return;
    }
    else
    {
        while(!s.empty())
        {
            cur = s.top();
            if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
            {
                cout << cur->data << " ";
                s.pop();
                pre = cur;
            }
            else
            {
                //顺序很重要!
                if(cur->rchild != NULL)
                    s.push(cur->rchild);
                if(cur->lchild  != NULL)
                {
                    s.push(cur->lchild);
                }
            }
        }
    }
}

//按层次遍历二叉树 用队列实现
void levelTraverse(BTree tree)
{
    queue<BTree> que;
    if(!tree)
    {
        cout << "二叉树为空" << endl;
        return;
    }
    else
    {
        while(tree)
        {
            cout << tree->data << " ";
            if(tree->lchild)
                que.push(tree->lchild);
            if(tree->rchild)
                que.push(tree->rchild);
            if(que.empty())
                break;
            tree = que.front();
            que.pop();
        }
    }
}

//求二叉树的深度
int depthTree(BTree tree)
{
    int dep = 0, depL, depR;
    if(!tree) 
        dep = 0;
    else
    {
        depL = depthTree(tree->lchild);
        depR = depthTree(tree->rchild);
        dep = 1 + (depL > depR ? depL : depR);
    }
    return dep;
}

//求叶子结点的个数
int sumLeaf(BTree tree)
{
    int sum = 0, m, n;
    if(tree)
    {
        //->的优先级高于! 左子树和右子树都为空
        if((!tree->lchild) && (!tree->rchild))
            sum++;
        m = sumLeaf(tree->lchild);
        sum += m;
        n = sumLeaf(tree->rchild);
        sum += n;

    }
    else
        return 0;
    return sum;
}

//度为2的结点数目
int sumDoublePoint(BTree tree)
{
    int sum = 0, m, n;
    if(tree)
    {
        if((tree->lchild != NULL) && (tree->rchild != NULL))
            sum++;
        m = sumDoublePoint(tree->lchild);
        sum += m;
        n = sumDoublePoint(tree->rchild);
        sum += n;
    }
    else
        return 0;
    return sum;
}

//度为1的结点数目
int sumSinglePoint(BTree tree)
{
    int sum = 0;
    if(!tree)
        return 0;
    else
    {
        if(tree->lchild != NULL && tree->rchild != NULL)
        {
            sumSinglePoint(tree->lchild);
            sumSinglePoint(tree->rchild);
        }
        if(tree->lchild != NULL && tree->rchild == NULL)
        {
            sum += 1;
            sumSinglePoint(tree->lchild);
        }
        if(tree->lchild == NULL && tree->rchild != NULL)
        {
            sum += 1;
            sumSinglePoint(tree->rchild);
        }
    }
    return sum;
}

//查找树中是否存在要找的元素
//按递归的方式来查找,必须在找的第一时间就输出信息,否则递归的嵌套会使结果掩盖
bool search(BTree tree, int search_num)
{
    if(tree)
    {
        if(tree->data == search_num)
        {
            cout << tree->data << "==" << search_num << endl;
            return true;
        }
        else
        {
            if(search(tree->lchild, search_num))
            {}
            else
              search(tree->rchild, search_num);
        }
    }
    else
        return false;
}

//寻找给定结点的父结点
//测试案例
int main()
{
    int search_num;
    BTree T;
    T = CreateBinaryTree(T);

    cout <<"递归前序遍历:";
    preorderTraverse(T);
    cout << endl;
    cout <<"非递归前序遍历:";
    preorderNotRecursion(T);
    cout << endl;

    cout <<"递归中序遍历:";
    inorderTraverse(T);
    cout << endl;
    cout <<"非递归中序遍历:";
    inorderNotRecursion(T);
    cout << endl;

    cout <<"递归后序遍历:";
    postorderTraverse(T);
    cout << endl;
    cout <<"非递归后序遍历:";
    postorderNotRecursion(T);
    cout << endl;
    
    cout <<"按层次遍历二叉树:";
    levelTraverse(T);
    cout << endl;

    cout << "树的深度: " << depthTree(T) << endl;
    cout << "叶子结点数: " << sumLeaf(T) << endl;
    cout << "度为1的结点个数: "<< sumSinglePoint(T) << endl;
    cout << "度为2的结点个数: "<< sumDoublePoint(T) << endl;

    cout << "请输入要查找的元素:";
    cin >> search_num;
    if(search(T, search_num))
        cout << "111" << endl;
    else
        cout << "000" << endl;

    return 0;
}

image

图中所建的二叉树如下所示:

image

posted on 2015-08-27 09:40  寒叶峰  阅读(1581)  评论(0编辑  收藏  举报

导航