/*
在这三个遍历中,只调用了一个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;
}
有关二叉树求解模板
猜你喜欢
转载自blog.csdn.net/jkdd123456/article/details/80200789
今日推荐
周排行