有关二叉树求解模板

/*
在这三个遍历中,只调用了一个Visit()
函数,只输出此时的根节点即可
原因是:
每访问一个点,都可以是一个根节点,然后都可以有左右根结点*/
/*
BiTree 本身已经是一个指针了,为什么要用Bitree &T呢?
首先明确一个问题:Bitree &T 中的&是引用,这个也就是取地址的意思,
这个只有C++中才有,你也可以用C中的指针,用Bitree *T,
但是这样你调用Insert时就必须这样调用Insert(&T). */
/*
Bitree T -> 定义Bitree一个实例对象:T;
Bitree &T -> 定义Bitree的实例对象的引用,就是一个已经定义的对象的别名,需要初始化;
解释:
以下程序中,n是m的一个引用(reference),m是被引用物(referent)。
 int m;
 int &n = m;
n相当于m的别名(绰号),对n的任何操作就是对m的操作。*/
/*
BiTNode   BiTNode类型,
*BiTree     指向BiTNode类型的指针;
定义一个BiTNode类型a:
BiTNode a ;
BiTree a  =  BiTNode *a;
*/


----------
代码:
#include<iostream>
#include<stack>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
typedef struct BiTNode 		//二叉树结点
{
    char data; 	数据
    struct BiTNode *lchild,*rchild;	//左右孩子指针
} BiTNode,*BiTree;
//重命名 将struct BiTNode命名为BiTNode,将struct BiTNode*命名为BiTree
//按先序序列创建二叉树
int CreateBiTree(BiTree &T)	
// 对 T 的引用,所以加 取地址符(要修改 T)
{
    char data;
    //按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
    scanf("%c",&data);
    if(data == '#')
    {
        T = NULL;		//表示的是 此时的 根是个空的
    }
    else
    {
        T = (BiTree)malloc(sizeof(BiTNode));	//动态分配,返回struct BITNode* 的指针
        T->data = data;		   		 //生成根结点
        CreateBiTree(T->lchild);			 //构造左子树
   		CreateBiTree(T->rchild);		    //构造右子树

    }
    return 0;
}
//输出的代码
void Visit(BiTree T)		//只是输出 并不是修改,所以不用写成 &T
{
    if(T->data != '#')
    {
        printf("%c ",T->data);	//输出
    }
}
//先序遍历
void PreOrder(BiTree T)
{
    if(T != NULL)
    {
        Visit(T);			//访问根节点,并且只在访问根结点的时候输出
        PreOrder(T->lchild);	 //访问左子结点
        PreOrder(T->rchild); 	//访问右子结点

    }
}												
//中序遍历
void InOrder(BiTree T)
{
    if(T != NULL)
    {
          nOrder(T->lchild);	//访问左子结点
   Visit(T);			//访问根节点
InOrder(T->rchild);	//访问右子结点

    }
}
//后序遍历
void PostOrder(BiTree T)
{
    if(T != NULL)
    {
        //访问左子结点
        PostOrder(T->lchild);
        //访问右子结点
        PostOrder(T->rchild);
        //访问根节点
        Visit(T);
    }
}
//层次遍历
void LevelOrder(BiTree T)
{
    BiTree p = T;
    queue<BiTree> queue;		  //队列
queue.push(p);		      //根节点入队
    while(!queue.empty())		  //队列不空循环
    {
        p = queue.front();		//对头元素出队
printf("%c ",p->data);	 //访问p指向的结点
        queue.pop();			//退出队列
        if(p->lchild != NULL)	 //左子树不空,将左子树入队
 {
  queue.push(p->lchild);
        }
        if(p->rchild != NULL)	 //右子树不空,将右子树入队
        {
            queue.push(p->rchild);
        }
    }
}
//叶子节点个数
int TreeCount(BiTree T)
{
    if(T == NULL)
    {
        return 0;
    }
    else if ((T->lchild==NULL) && (T->rchild==NULL))
    {
        return 1;		//如果此节点是叶子节点,返回1 即它本身是一个节点。
    }
    else
    {
        return TreeCount(T->lchild)+TreeCount(T->rchild);
//如果左右孩子不空,返回左孩子+右孩子节点数。
    }
}
//求深度
int TreeDepth(BiTree T)
{
    int rightdep=0;
    int leftdep=0;
    if(T==NULL)		    //如果是空树,返回-1
        return -1;
    if(T->lchild!=NULL)		//如果左孩子不空,继续递归,如果为空,返回-1
        leftdep=TreeDepth(T->lchild);
    else
        leftdep=-1;
    if(T->rchild!=NULL)		 //如果右孩子不空,继续递归,如果为空,返回-1
        rightdep=TreeDepth(T->rchild);
    else
        rightdep=-1;
return (rightdep>leftdep) ? rightdep+1 : leftdep+1;	
//左右孩子都递归完,返回左右孩子中较大的值
}
//交换左右孩子
void TreeExchange(BiTree T)
{
    if(T!=NULL)
    {
        BiTree temp;
        if(T->lchild||T->rchild)
        {
            temp=T->lchild;
            T->lchild=T->rchild;
            T->rchild=temp;
            TreeExchange(T->lchild);
            TreeExchange(T->rchild);
        }
    }
}
int main()
{
    BiTree T;
    CreateBiTree(T);
    printf("先序遍历:\n");
    PreOrder(T);
    printf("\n\n");

    printf("中序遍历:\n");
    InOrder(T);
    printf("\n\n");

    printf("后序遍历:\n");
    PostOrder(T);
    printf("\n\n");

    printf("层次遍历:\n");
    LevelOrder(T);
    printf("\n\n");

    int deep=TreeDepth(T);
    printf("树的深度:%d\n\n",deep+1);

    int number=TreeCount(T);
    printf("叶子节点个数:%d\n\n",number);

    printf("交换左右孩子成功\n\n");
    TreeExchange(T);

    printf("层次遍历:\n");
    LevelOrder(T);
    printf("\n");
    printf("\n");
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值