c++实现二叉树的查找,插入,删除,深度,叶子节点数,度为1的节点数(递归方法)及运行实例结果

这是算法导论中二叉树搜索的一个例题

二叉树为


c++代码为

#include<iostream>
#define N 7
using namespace std;
//二叉树节点类
class node
{
public:
    int data;
    node *leftChild;
    node *rightChild;
};
typedef node *BiTree;//等价
//创建节点
node *createNode(int value)
{
    node *q=new node;
    q->leftChild=NULL;
    q->rightChild=NULL;
    q->data=value;

    return q;
}
//创建二叉树
BiTree createBiTree()
{
    node *p[N]={NULL};
    int array[6]={6,5,7,2,5,8};
    for(int i=0;i<6;++i)
        p[i]=createNode(array[i]);
    for(int i=0;i<N/2;++i)
    {
        p[i]->leftChild=p[i*2+1];
        p[i]->rightChild=p[i*2+2];
    }
    return p[0];//返回根节点
}

//求二叉树的深度
int depth(BiTree tree)
{
    int dep=0;
    int leftDep,rightDep;
    if(!tree)
        dep=0;
    else
    {
        leftDep=depth(tree->leftChild);
        rightDep=depth(tree->rightChild);
        dep=1+(leftDep>rightDep?leftDep:rightDep);
    }
    return dep;
}
//度为1的节点数,即只有一个分支
int numOfOneDgree(BiTree tree)
{
    int sum=0;
    int leftNum,rightNum;
    if(tree)
    {
        if(((tree->leftChild!=NULL)&&(tree->rightChild==NULL))||((tree->leftChild==NULL)&&(tree->rightChild!=NULL)))
            sum++;
        leftNum=numOfOneDgree(tree->leftChild);//递归
        sum+=leftNum;
        rightNum=numOfOneDgree(tree->rightChild);
        sum+=rightNum;
    }
    return sum;
}
//叶子节点的个数
int sumOfSubLeft(BiTree tree)
{
    int sum=0;
    int leftNum,rightNum;
    if(tree)
    {
        if((!tree->leftChild)&&(!tree->rightChild))//左右节点均为NULL
            sum++;
        leftNum=sumOfSubLeft(tree->leftChild);
        sum+=leftNum;
        rightNum=sumOfSubLeft(tree->rightChild);
        sum+=rightNum;
    }
    return sum;
}
//查找

bool search(BiTree tree,int searchNum)
{
    if(tree==NULL)
    {
        return 0;
    }
    else
    {
        if(tree->data==searchNum)
        {
            return 1;
        }
        else
        {
            if(searchNum<tree->data)
                return search(tree->leftChild,searchNum);
            else
                return search(tree->rightChild,searchNum);
        }
    }
}
//访问节点中的数据
int visit(BiTree tree)
{
    return tree->data;
}
// 中序遍历
void inorderTreeWalk(BiTree tree)
{
    if(tree)
    {
        inorderTreeWalk(tree->leftChild);
        cout << visit(tree) << " ";
        inorderTreeWalk(tree->rightChild);
    }
}
//插入
void insertNode(node* *tree ,int x)
{
    if(*tree==NULL)//新建一个根节点
    {
        node *p=new node;
        p->data=x;
        p->leftChild=NULL;
        p->rightChild=NULL;
        *tree=p;
        return;
    }
    else if(x<(*tree)->data)
        insertNode(&((*tree)->leftChild),x);
    else
        insertNode(&((*tree)->rightChild),x);
}
//删除,比较麻烦,分几种情况
int deleteNode(node* *tree,int x)
{
    node *temp=*tree;
    if(*tree==NULL)
        return 0;
    if(x<(*tree)->data)
        return deleteNode(&((*tree)->leftChild),x);
    if(x>(*tree)->data)
        return deleteNode(&((*tree)->rightChild),x);
    if((*tree)->leftChild==NULL)//左子树为空,且删除元素等于根节点,把右子树作为整个树
    {
        *tree=(*tree)->rightChild;
        free(temp);
        return 1;
    }
    else
    {
        if((*tree)->leftChild->rightChild==NULL)//前驱节点为空时,把左孩子节点赋给根节点,再从左子树中删除根节点
            {
                (*tree)->data=(*tree)->leftChild->data;
                return deleteNode(&((*tree)->leftChild),(*tree)->data);
            }
        else
        {//找到前驱节点,再把该节点赋给根节点,最后删除该根节点
            node *p1=*tree;
            node *p2=p1->leftChild;
            while(p2->rightChild!=NULL)
            {
                p1=p2;
                p2=p2->rightChild;
            }
            (*tree)->data=p2->data;
            return deleteNode(&(p1->rightChild),p2->data);
        }
    }
}

int main()
{
    BiTree tree;
    tree=createBiTree();
    cout<<"二叉树的深度为:"<<depth(tree)<<endl;
    cout<<"二叉树的叶子节点个数为:"<<sumOfSubLeft(tree)<<endl;
    cout<<"二叉树中度为1的个数为:"<<numOfOneDgree(tree)<<endl;
    cout<<"请输入要查找的数,输入1000结束查找"<<endl;
    int n,m,w;
    while(1)
    {
        cin>>n;
        if(n==1000)
            break;
        else
        {
            if(search(tree,n))
                cout<<"查找到值为"<<n<<"的数"<<endl;
            else
                cout<<"未查到到值为"<<n<<"的数"<<endl;
        }

    }
    cout << endl<< "中序遍历结果为:";
    inorderTreeWalk(tree);

    cout<<endl<<"请输入要插入的值:";
    cin>>m;
    insertNode(&tree,m);
    cout << "插入值后中序遍历结果为:";
    inorderTreeWalk(tree);

    cout<<endl<<"请输入要删除的值:";
    cin>>w;
    deleteNode(&tree,w);
    cout << "删除值后中序遍历结果为:";
    inorderTreeWalk(tree);
    return 0;
}

运行结果为




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值