#include<bits/stdc++.h>
using namespace std;
#define MaxSize 100
#define ElemType char
typedef struct node
{
ElemType data;//数据元素
struct node *lchild;//指向左孩子结点
struct node *rchild;//指向右孩子结点
}BTNode;
//1.创建二叉树
void CreateBTree(BTNode *&b , char *str)//
{
BTNode *St[MaxSize],*p;//St数组作为顺序栈
int top=-1,k,j=0; //top 为栈顶指针
char ch;
b = NULL;//初始时候二叉链表为空
ch = str[j];
while(ch!='\0')
{
switch(ch)//遍历str中的每一个字符
{
case '(' : top++;St[top] = p;k=1;break; //开始处理左孩子结点
case ')' : top--;break; //栈顶处理完毕 退栈
case ',' : k=2;break; //开始处理右结点
default : p = new BTNode ; //创建一个结点
p->data = ch;//存放结点值
p->lchild = p->rchild = NULL; //左右都初始化为空
if(b==NULL) //如果还没有存放根节点
{
b = p;
}
else
{
switch (k)
{
case 1:St[top]->lchild = p;break; //创建新结点作为栈顶的左节点
case 2:St[top]->rchild = p;break; //创建新结点作为栈顶的右节点
}
}
}
j++;
ch = str[j];
}
}
//2.销毁二叉树
void DestoryBTree(BTNode *&b)
{
if(b!=NULL)
{
DestoryBTree(b->lchild);
DestoryBTree(b->rchild);
delete b;
}
}
//3.查找结点
BTNode *FindNode(BTNode *b,ElemType x)
{
BTNode *p;
if(b==NULL)//当前顶点是空 就返回NULL
{
return NULL;
}
else if(b->data == x)//当前顶点是x 就返回这个值
{
return b;
}
else //当前顶点不是x 且存左右结点
{
p = FindNode(b->lchild,x);//先去左孩子找x
if(p!=NULL)//找到答案了就返回
{
return p;
}
else return FindNode(b->rchild,x);
}
}
//4.找孩子结点
BTNode *LchildNode(BTNode *p) //返回结点p的左孩子结点地址
{
return p->lchild;
}
BTNode *RchildNode(BTNode *p) //返回结点p的左孩子结点地址
{
return p->rchild;
}
//5.求高度
int BTHeight(BTNode *b)
{
int lchildh,rchildh;
if(b==NULL) return (0);//空树的高度为0
else
{
//某个顶点左右两边的高度
lchildh = BTHeight(b->lchild);//求左子树的高度
rchildh = BTHeight(b->rchild);//求右子树的高度
return (lchildh > rchildh) ? (lchildh + 1) : (rchildh + 1);
}
}
//6.输出二叉树
void DispBTree(BTNode *b)
{
if(b!=NULL)
{
printf("%c",b->data);
if(b->lchild!=NULL || b->rchild!=NULL)
{
printf("(");
DispBTree(b->lchild);
if(b->rchild!=NULL) printf(",");
DispBTree(b->rchild);
printf(")");
}
}
}
//7.查找二叉树的节点个数(遍历每一个节点)
int FindOrder(BTNode *b)
{
if(b!=NULL)
{
return FindOrder(b->lchild) + FindOrder(b->rchild) + 1;
}
else
return 0;
}
//8.输出该二叉树双分支结点的个数
int DoubleOrder(BTNode *b)
{
if(b!=NULL&&b->lchild!=NULL && b->rchild!=NULL)//同时存在双节点
{
int sum = 1;
sum += DoubleOrder(b->lchild) ;
sum += DoubleOrder(b->rchild) ;
return sum;
}
else if(b!=NULL&&(b->lchild==NULL || b->rchild==NULL)) //没有同时存在双节点
{
int sum =0;
sum += DoubleOrder(b->lchild) ;
sum += DoubleOrder(b->rchild) ;
return sum;
}
else return 0;//当结点是空结点的时候返回0
}
//9.输出该二叉树单分支结点的个数
int FindOne(BTNode *b)
{
if(b!=NULL&&b->lchild!=NULL && b->rchild!=NULL)//同时存在双节点
{
int sum = 0;
sum += FindOne(b->lchild) ;
sum += FindOne(b->rchild) ;
return sum;
}
else if(b!=NULL && b->lchild==NULL && b->rchild!=NULL) //没有同时存在双节点
{
int sum = 1;
sum += FindOne(b->lchild) ;
sum += FindOne(b->rchild) ;
return sum;
}
else if(b!=NULL&&b->lchild!=NULL && b->rchild==NULL) //没有同时存在双节点
{
int sum = 1;
sum += FindOne(b->lchild) ;
sum += FindOne(b->rchild) ;
return sum;
}
else return 0;//什么都不存在
}
//10.求宽度
int Wide(BTNode *b)
{
if(b==NULL) return 0;
else
{
BTNode *Q[FindOrder(b)];//Q是队列,元素为二叉树结点的指针,容量足够大
int front=1,rear=1,last=1;//对头指针、队尾指针、last为最右结点在队列中的位置
int res=0,maxw=0; //res记局部宽度,maxw记最大宽度
Q[rear]=b;//根节点先入队
while(front<=last)
{
BTNode *p=Q[front++];//先赋值在出队
res++;//同层元素加一
if(p->lchild!=NULL) Q[++rear] = p->lchild;//左结点入队
if(p->rchild!=NULL) Q[++rear] = p->rchild;//右结点入队
if(front>last)//某一层结束
{
last = rear;
if(res>maxw) maxw = res;
res=0;
}
}
return maxw;
}
}
//11.任意给定该二叉树的两个结点,输出它们的最近的公共祖先
//(左右中--后序遍历 + dfs)
BTNode *Find(BTNode *root,ElemType p,ElemType q)
{
if(root==NULL || root->data==p || root->data==q) return root;
BTNode *left = Find(root->lchild,p,q);//看看root左边有没有p或者q
BTNode *right = Find(root->rchild,p,q);//看看root右边有没有p或者q
if(left!=NULL && right!=NULL) return root;//一直往上面返回
if(left==NULL && right!=NULL ) return right; //右边存在返回右边
if(left!=NULL && right==NULL ) return left;//左边存在返回左边
}
int main()
{
BTNode *b,*p;
//1.创建该二叉树
ElemType str[]={"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))"};
CreateBTree(b,str);
cout<<"二叉树btree:\n";
DispBTree(b);
//2.输入某个结点的左右结点
ElemType x;
cout<<"\n请输入一个结点的值:";cin>>x;
p = b;
if(FindNode(p,x) == NULL )
{
cout<<"\n你输入的结点值不存在!"<<endl;
}
else
{
BTNode *q = FindNode(p,x);
if(LchildNode(q)!=NULL)
printf("左节点的值为%c\n\n",LchildNode(q)->data);
else printf("左节点为NULL\n\n");
if(RchildNode(q)!=NULL)
printf("右节点的值为%c\n\n",RchildNode(q)->data);
else printf("右节点为NULL\n\n");
}
//3.输出该二叉树的高度
printf("该二叉树的高度为:%d\n",BTHeight(b));cout<<endl;
//4.输出该二叉树的结点个数
printf("该二叉树的结点个数%d个\n",FindOrder(b));cout<<endl;
//5.输出该二叉树双分支结点的个数
printf("该二叉树的双分支结点个数%d个\n",DoubleOrder(b));cout<<endl;
//6.输出该二叉树单分支结点的个数
printf("该二叉树的单分支结点个数%d个\n",FindOne(b));cout<<endl;
//7.输出该二叉树叶子结点的个数。
printf("该二叉树叶子结点的个数为%d个\n",FindOrder(b)-DoubleOrder(b)-FindOne(b));cout<<endl;
//8.输出该二叉树的宽度
printf("输出该二叉树的宽度%d\n",Wide(b)); cout<<endl;
//9.任意给定该二叉树的两个结点,输出它们的最近的公共祖先
//(上中下后序遍历 + dfs)
ElemType n,m;
printf("输入你要查找的两个结点");cin>>n>>m;
printf("输出这这个两个结点最近共同父结点是%c\n",Find(b,n,m)->data); cout<<endl;
//10.摧毁二叉树
DestoryBTree(b);
return 0;
}
二叉树的基本运用1
最新推荐文章于 2024-08-25 06:11:42 发布
这篇文章详细介绍了如何使用C++实现二叉树的各种操作,包括从括号表示的字符串创建二叉树、销毁二叉树、查找节点、获取节点的孩子、计算树的高度、输出树的结构、统计节点数量、计算双分支和单分支节点个数、计算宽度以及寻找两个节点的最近公共祖先。
摘要由CSDN通过智能技术生成