1.统计二叉树双孩子/单孩子/叶子结点数
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//本题一定注意怎么避免全局变量的使用,通过递归实现算法
//定义二叉树
typedef struct erchashu
{
char fuhao;
erchashu* lc;//左
erchashu* rc;//右
}*twotree;
//创建二叉树
twotree creat()
{
twotree tree;
char c;
c=getchar();
if(c=='#')
{
tree=NULL;
}
else
{
tree=(twotree)malloc(sizeof(erchashu));
tree->fuhao=c;
tree->lc=creat();
tree->rc=creat();
}
return tree;
}
//广义表输出二叉树
void visit(char e)
{
cout<<e;
}
void shuchu(twotree tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->lc||tree->rc)
{
cout<<'(';
shuchu(tree->lc,visit);
cout<<',';
shuchu(tree->rc,visit);
cout<<')';
}
}
//统计双孩子结点
int doublec(twotree tree)
{
int bencengjiedian;
if(!tree)
{
return 0;
}
if(tree->lc&&tree->lc)//如果此节点左右都有
{
bencengjiedian=1;
}
else
{
bencengjiedian=0;
}
return bencengjiedian+doublec(tree->lc)+doublec(tree->rc);
}
//统计单孩子节点
int singlec(twotree tree)
{
int bencengjiedian0;
if(!tree)
{
return 0;
}
if((tree->lc&&!tree->rc)||(tree->rc&&!tree->lc))//左右至少空了一个
{
bencengjiedian0=1;
}
else
{
bencengjiedian0=0;
}
return bencengjiedian0+singlec(tree->lc)+singlec(tree->rc);
}
//统计叶子
int leaf(twotree tree)
{
if(!tree)
{
return 0;
}
if(!tree->lc&&!tree->rc)
{
return 1;
}
return leaf(tree->lc)+leaf(tree->rc);
}
int main()
{
printf("请以先序序列输入您的二叉树,并用“#”表示取消建立子树节点(例如:ABD##EH###CF#I##G##)\n");
twotree T;
T=creat();
shuchu(T,visit);
printf("\n");
int cnt1;
int cnt2;
int cnt3;
cnt1=doublec(T);
cnt2=singlec(T);
cnt3=leaf(T);
cout<<"共有"<<cnt1<<"个具有双孩子的结点"<<endl;
cout<<"共有"<<cnt2<<"个具有单孩子的结点"<<endl;
cout<<"共有"<<cnt3<<"个叶子结点"<<endl;
}
2.判断严格二叉树
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//本题一定注意怎么避免全局变量的使用,通过递归实现算法
//定义二叉树
typedef struct erchashu
{
char fuhao;
erchashu* lc;//左
erchashu* rc;//右
}*twotree;
//创建二叉树
twotree creat()
{
twotree tree;
char c;
c=getchar();
if(c=='#')
{
tree=NULL;
}
else
{
tree=(twotree)malloc(sizeof(erchashu));
tree->fuhao=c;
tree->lc=creat();
tree->rc=creat();
}
return tree;
}
//广义表输出二叉树
void visit(char e)
{
cout<<e;
}
void shuchu(twotree tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->lc||tree->rc)
{
cout<<'(';
shuchu(tree->lc,visit);
cout<<',';
shuchu(tree->rc,visit);
cout<<')';
}
}
//判断严格二叉树
bool panduan(twotree tree)
{
if(!tree)
{
return true;
}
if((!tree->lc&&tree->rc)||(!tree->rc&&tree->lc))
{
return false;
}
return panduan(tree->lc)&&panduan(tree->rc);
}
int main()
{
printf("请以先序序列输入您的二叉树,并用“#”表示取消建立子树节点(例如:ABD##EH###CF#I##G##)\n");
twotree T;
T=creat();
shuchu(T,visit);
printf("\n");
if(panduan(T))
{
printf("是严格的\n");
}
else
{
printf("不是严格的\n");
}
return 0;
}
3.寻找二叉树有无x结点
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//定义二叉树
typedef struct erchashu
{
char fuhao;
erchashu* lc;//左
erchashu* rc;//右
}*twotree;
//创建二叉树
twotree creat()
{
twotree tree;
char c;
c=getchar();
if(c=='#')
{
tree=NULL;
}
else
{
tree=(twotree)malloc(sizeof(erchashu));
tree->fuhao=c;
tree->lc=creat();
tree->rc=creat();
}
return tree;
}
//广义表输出二叉树
void visit(char e)
{
cout<<e;
}
void shuchu(twotree tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->lc||tree->rc)
{
cout<<'(';
shuchu(tree->lc,visit);
cout<<',';
shuchu(tree->rc,visit);
cout<<')';
}
}
//寻找x结点
twotree found(twotree tree,char x)
{
twotree tree0;
if(!tree)
{
return NULL;
}
if(x==tree->fuhao)
{
return tree;
}
tree0=found(tree->lc,x);
if(tree0)
{
return tree0;
}
return found(tree->rc,x);
}
int main()
{
char zifu;
printf("请以先序序列输入您的二叉树,并用“#”表示取消建立子树节点(例如:ABD##EH###CF#I##G##)\n");
twotree T;
T=creat();
printf("请输入您想要查找的字符:\n");
cin>>zifu;
shuchu(T,visit);
printf("\n");
if(found(T,zifu))
{
cout<<"x的地址为"<<found(T,zifu)<<endl;
}
else
{
cout<<"没找到x"<<endl;
}
}
4.求以x为根节点的子树深度
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//定义二叉树
typedef struct erchashu
{
char fuhao;
erchashu* lc;//左
erchashu* rc;//右
}*twotree;
//创建二叉树
twotree creat()
{
twotree tree;
char c;
c=getchar();
if(c=='#')
{
tree=NULL;
}
else
{
tree=(twotree)malloc(sizeof(erchashu));
tree->fuhao=c;
tree->lc=creat();
tree->rc=creat();
}
return tree;
}
//广义表输出二叉树
void visit(char e)
{
cout<<e;
}
void shuchu(twotree tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->lc||tree->rc)
{
cout<<'(';
shuchu(tree->lc,visit);
cout<<',';
shuchu(tree->rc,visit);
cout<<')';
}
}
//寻找x结点
twotree found(twotree tree,char x)
{
twotree tree0;
if(!tree)
{
return NULL;
}
if(x==tree->fuhao)
{
return tree;
}
tree0=found(tree->lc,x);
if(tree0)
{
return tree0;
}
return found(tree->rc,x);
}
//利用寻找到的x结点的地址,来找x子树深度
int depth(twotree tree)
{
int dl,dr;
if(!tree)
{
return 0;
}
dl=depth(tree->lc);
dr=depth(tree->rc);
if(dl>dr)
{
return dl+1;
}
else
{
return dr+1;
}
}
int depth1(twotree tree,char x)
{
return depth(found(tree,x));
}
int main()
{
char zifu;
printf("请以先序序列输入您的二叉树,并用“#”表示取消建立子树节点(例如:ABD##EH###CF#I##G##)\n");
twotree T;
T=creat();
printf("请输入您想要查找的字符:\n");
cin>>zifu;
shuchu(T,visit);
printf("\n");
if(depth1(T,zifu))
{
cout<<"以x为结点的子树的深度为"<<depth1(T,zifu)<<endl;
}
else
{
cout<<"没找到x"<<endl;
}
}
5.删除二叉树中所有根节点为x的子树
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//定义二叉树
typedef struct erchashu
{
char fuhao;
erchashu* lc;//左
erchashu* rc;//右
}*twotree;
//创建二叉树
twotree creat()
{
twotree tree;
char c;
c=getchar();
if(c=='#')
{
tree=NULL;
}
else
{
tree=(twotree)malloc(sizeof(erchashu));
tree->fuhao=c;
tree->lc=creat();
tree->rc=creat();
}
return tree;
}
//广义表输出二叉树
void visit(char e)
{
cout<<e;
}
void shuchu(twotree tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->lc||tree->rc)
{
cout<<'(';
shuchu(tree->lc,visit);
cout<<',';
shuchu(tree->rc,visit);
cout<<')';
}
}
//删除二叉树
void deletetree(twotree &tree)
{
if(!tree)
{
return;
}
deletetree(tree->lc);
deletetree(tree->rc);
delete tree;
}
//删除以x为根的二叉树
void deletextree(twotree &tree,char x)
{
if(!tree)
{
return;
}
if(tree->fuhao==x)
{
deletetree(tree);
tree=NULL;
}
else
{
deletextree(tree->lc,x);
deletextree(tree->rc,x);
}
}
int main()
{
char zifu;
printf("请以先序序列输入您的二叉树,并用“#”表示取消建立子树节点(例如:ABXE##F##D##CXH##X##G##)\n");
twotree T;
T=creat();
printf("请输入您想要查找的字符:\n");
cin>>zifu;
cout<<"您输入的二叉树广义表表示为:"<<endl;
shuchu(T,visit);
printf("\n");
deletextree(T,zifu);
cout<<"删除x根节点的子树后的二叉树广义表表示为:"<<endl;
shuchu(T,visit);
}
6.判断完全二叉树
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//定义二叉树
typedef struct erchashu
{
char fuhao;
erchashu* lc;//左
erchashu* rc;//右
}*twotree;
//定义链队列
typedef struct Qnode
{
twotree data;
Qnode *next;
}*lianduilie;
struct liandui
{
lianduilie front,rear;
};
//初始化链队
void duiinit(liandui &Q)
{
Q.front=new Qnode;
Q.front->next=NULL;
Q.rear=Q.front;
}
//入队
void Enqueue(liandui &Q,twotree e)
{
lianduilie p;
p=new Qnode;
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
bool Dequeue(liandui &Q,twotree &e)
{
lianduilie p;
if(Q.front==Q.rear)
{
return false;
}
p=Q.front;
Q.front=p->next;
e=Q.front->data;
delete p;
return true;
}
//创建二叉树
twotree creat()
{
twotree tree;
char c;
c=getchar();
if(c=='#')
{
tree=NULL;
}
else
{
tree=(twotree)malloc(sizeof(erchashu));
tree->fuhao=c;
tree->lc=creat();
tree->rc=creat();
}
return tree;
}
//广义表输出二叉树
void visit(char e)
{
cout<<e;
}
void shuchu(twotree tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->lc||tree->rc)
{
cout<<'(';
shuchu(tree->lc,visit);
cout<<',';
shuchu(tree->rc,visit);
cout<<')';
}
}
//判断完全二叉树
bool panduan(twotree tree)
{
liandui q;
twotree p;
if(!tree)
{
return true;
}
duiinit(q);
Enqueue(q,tree);
while(Dequeue(q,p))
{
if(!p)
{
break;
}
Enqueue(q,p->lc);
Enqueue(q,p->rc);
}
while(Dequeue(q,p))
{
if(p)
{
return false;
}
}
return true;
}
int main()
{
char zifu;
printf("请以先序序列输入您的二叉树,并用“#”表示取消建立子树节点(例如:ABD##EH###CF#I##G##)\n");
twotree T;
T=creat();
shuchu(T,visit);
printf("\n");
if(panduan(T))
{
cout<<"是完全二叉树"<<endl;
}
else
{
cout<<"不是完全二叉树"<<endl;
}
}
7.先序遍历+中序遍历建立二叉链表
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef struct erchashu
{
char fuhao;
erchashu* lc;//左
erchashu* rc;//右
}*twotree;
bool chuangzaoerchashu(twotree &T,char A[],char B[],int n)
{
int k;
if(n==0)
{
T=NULL;
return true;
}
k=0;
while(k<n&&B[k]!=A[0])
{
k++;
}
if(k==n)
{
T=NULL;
return false;
}
T=new erchashu;
T->fuhao=A[0];
return chuangzaoerchashu(T->lc,A+1,B,k)&&chuangzaoerchashu(T->rc,A+k+1,B+k+1,n-k-1);
}
//广义表输出二叉树
void visit(char e)
{
cout<<e;
}
void shuchu(twotree tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->lc||tree->rc)
{
cout<<'(';
shuchu(tree->lc,visit);
cout<<',';
shuchu(tree->rc,visit);
cout<<')';
}
}
int main()
{
twotree T;
int n;
cout<<"请输入二叉树的结点个数:"<<endl;
cin>>n;
char *A=(char *)malloc(sizeof(char)*n);
char *B=(char *)malloc(sizeof(char)*n);
cout<<"请输入二叉树的先序序列"<<endl;
int i;
for(i=0;i<n;i++)
{
cin>>A[i];
}
cout<<"请输入二叉树的中序序列"<<endl;
for(i=0;i<n;i++)
{
cin>>B[i];
}
if(chuangzaoerchashu(T,A,B,n))
{
shuchu(T,visit);
}
return 0;
}
8.二叉树广义表形式输入建立二叉链表
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef struct erchashu
{
char fuhao;
erchashu* lc;//左
erchashu* rc;//右
}*twotree;
bool chuangzaoerchashu(twotree &T,char A[],int n,int &i)
{
i++;
if(i==n)
{
return false;
}
if(A[i]=='#')
{
T=NULL;
return true;
}
if(A[i]<'A'||A[i]>'Z')
{
return false;
}
T=new erchashu;
T->fuhao=A[i];
if(i==n-1||A[i+1]==','||A[i+1]==')')
{
T->lc=NULL;
T->rc=NULL;
return true;
}
if(A[i+1]!='(')
{
return false;
}
i++;
if(!chuangzaoerchashu(T->lc,A,n,i))
{
return false;
}
i++;
if(i==n||A[i]!=',')
{
return false;
}
if(!chuangzaoerchashu(T->rc,A,n,i))
{
return false;
}
if(!T->lc&&!T->rc)
{
return false;
}
i++;
if(i==n||A[i]!=')')
{
return false;
}
return true;
}
bool chuangzaoerchashu(twotree &T,char A[])
{
int i=-1;
int n=strlen(A);
return chuangzaoerchashu(T,A,n,i)&&(i==n-1);
}
//先序序列输出二叉树
void visit(char e)
{
cout<<e;
}
void shuchu(twotree tree,void visit(char))
{
if(!tree)
{
return;
}
visit(tree->fuhao);
shuchu(tree->lc,visit);
shuchu(tree->rc,visit);
}
int main()
{
twotree T;
char A[100];
cout<<"请输入二叉树的广义表形式,例如:A(C(G(#,J),E(I(K,#),L)),B(D(#,H),F))"<<endl;
cin>>A;
if(chuangzaoerchashu(T,A))
{
shuchu(T,visit);
}
return 0;
}
9.森林的层序遍历
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//定义二叉树
typedef struct senlin
{
char fuhao;
senlin* fc;//左孩子
senlin* ns;//右兄弟
}*forest,*tree;
//定义链队列
typedef struct Qnode
{
forest data;
Qnode *next;
}*lianduilie;
struct liandui
{
lianduilie front,rear;
};
//初始化链队
void duiinit(liandui &Q)
{
Q.front=new Qnode;
Q.front->next=NULL;
Q.rear=Q.front;
}
//入队
void Enqueue(liandui &Q,forest e)
{
lianduilie p;
p=new Qnode;
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
bool Dequeue(liandui &Q,forest &e)
{
lianduilie p;
if(Q.front==Q.rear)
{
return false;
}
p=Q.front;
Q.front=p->next;
e=Q.front->data;
delete p;
return true;
}
//创建森林
forest creat()
{
forest sensen;
char c;
c=getchar();
if(c=='#')
{
sensen=NULL;
}
else
{
sensen=(forest)malloc(sizeof(senlin));
sensen->fuhao=c;
sensen->fc=creat();
sensen->ns=creat();
}
return sensen;
}
//广义表输出森林
void visit(char e)
{
cout<<e;
}
void shuchu(forest tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->fc||tree->ns)
{
cout<<'(';
shuchu(tree->fc,visit);
cout<<',';
shuchu(tree->ns,visit);
cout<<')';
}
}
//层序遍历森林
void cengxv(forest T,void visit(char))
{
liandui q;
tree x,y;
if(!T)
{
return;
}
duiinit(q);
for(x=T;x;x=x->ns)
{
Enqueue(q,x);
}
while(Dequeue(q,x))
{
visit(x->fuhao);
for(y=x->fc;y;y=y->ns)
{
Enqueue(q,y);
}
}
}
int main()
{
printf("请以先序序列输入您的森林(二叉树形式),并用“#”表示取消建立子树节点(例如:ADG#I##F#J##BCE###H##)\n");
forest T;
T=creat();
cout<<"您输入的森林的广义表表示为:";
shuchu(T,visit);
printf("\n");
cout<<"层序遍历的结果为:";
cengxv(T,visit);
}
10.统计树度为1和度为2的结点数目
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
typedef struct senlin
{
char fuhao;
senlin* fc;//左孩子
senlin* ns;//右兄弟
}*forest,*tree;
//定义链队列
typedef struct Qnode
{
forest data;
Qnode *next;
}*lianduilie;
struct liandui
{
lianduilie front,rear;
};
//初始化链队
void duiinit(liandui &Q)
{
Q.front=new Qnode;
Q.front->next=NULL;
Q.rear=Q.front;
}
//入队
void Enqueue(liandui &Q,forest e)
{
lianduilie p;
p=new Qnode;
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
bool Dequeue(liandui &Q,forest &e)
{
lianduilie p;
if(Q.front==Q.rear)
{
return false;
}
p=Q.front;
Q.front=p->next;
e=Q.front->data;
delete p;
return true;
}
//创建
forest creat()
{
forest sensen;
char c;
c=getchar();
if(c=='#')
{
sensen=NULL;
}
else
{
sensen=(forest)malloc(sizeof(senlin));
sensen->fuhao=c;
sensen->fc=creat();
sensen->ns=creat();
}
return sensen;
}
//广义表输出
void visit(char e)
{
cout<<e;
}
void shuchu(forest tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->fc||tree->ns)
{
cout<<'(';
shuchu(tree->fc,visit);
cout<<',';
shuchu(tree->ns,visit);
cout<<')';
}
}
//统计结点的度
int cnt1(tree T)
{
int n;
tree p;
if(!T)
{
return 0;
}
p=T->fc;
if(p&&!p->ns)
{
n=1;
}
else
{
n=0;
}
return n+cnt1(p)+cnt1(T->ns);
}
int cnt2(tree T)
{
int n;
tree p;
if(!T)
{
return 0;
}
p=T->fc;
if(p&&p->ns&&!p->ns->ns)
{
n=1;
}
else
{
n=0;
}
return n+cnt2(p)+cnt2(T->ns);
}
int main()
{
printf("请以先序序列输入您的树(二叉树形式),并用“#”表示取消建立子树节点(例如:ABD#EG##H##CF#J##I#K###)\n");
forest T;
T=creat();
cout<<"您输入的森林的广义表表示为:";
shuchu(T,visit);
printf("\n");
cout<<"度为1的结点个数为:"<<cnt1(T)<<endl;
cout<<"度为2的结点个数为:"<<cnt2(T)<<endl;
}
11.求非空树的度
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
typedef struct senlin
{
char fuhao;
senlin* fc;//左孩子
senlin* ns;//右兄弟
}*forest,*tree;
typedef tree QElemType;
#include "queue.cpp"
//创建
forest creat()
{
forest sensen;
char c;
c=getchar();
if(c=='#')
{
sensen=NULL;
}
else
{
sensen=(forest)malloc(sizeof(senlin));
sensen->fuhao=c;
sensen->fc=creat();
sensen->ns=creat();
}
return sensen;
}
//广义表输出
void visit(char e)
{
cout<<e;
}
void shuchu(forest tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->fc||tree->ns)
{
cout<<'(';
shuchu(tree->fc,visit);
cout<<',';
shuchu(tree->ns,visit);
cout<<')';
}
}
//计算树的度
int degree(tree T)
{
int d,dd;
liandui q;
tree x,y;
if(!T)
{
return -1;
}
duiinit(q);
Enqueue(q,T);
d=0;
while(Dequeue(q,x))
{
for(dd=0,y=x->fc;y;y=y->ns)
{
dd++;
Enqueue(q,y);
}
if(dd>d)
{
d=dd;
}
}
return d;
}
int main()
{
printf("请以先序序列输入您的树(二叉树形式),并用“#”表示取消建立子树节点(例如:ABD#EG##H##CF#J##I#K###)\n");
forest T;
T=creat();
cout<<"您输入的树的广义表表示为:";
shuchu(T,visit);
printf("\n");
cout<<"树的度为:"<<degree(T)<<endl;
}
12.求树的深度
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
typedef struct senlin
{
char fuhao;
senlin* fc;//左孩子
senlin* ns;//右兄弟
}*forest,*tree;
//创建
forest creat()
{
forest sensen;
char c;
c=getchar();
if(c=='#')
{
sensen=NULL;
}
else
{
sensen=(forest)malloc(sizeof(senlin));
sensen->fuhao=c;
sensen->fc=creat();
sensen->ns=creat();
}
return sensen;
}
//广义表输出
void visit(char e)
{
cout<<e;
}
void shuchu(forest tree,void visit(char))
{
if(!tree)
{
cout<<'#';
return;
}
visit(tree->fuhao);
if(tree->fc||tree->ns)
{
cout<<'(';
shuchu(tree->fc,visit);
cout<<',';
shuchu(tree->ns,visit);
cout<<')';
}
}
//求树的深度
int depth(tree T)
{
int dzuo,dyou;
if(!T)
{
return 0;
}
dzuo=depth(T->fc)+1;
dyou=depth(T->ns);
if(dzuo>dyou)
{
return dzuo;
}
else
{
return dyou;
}
}
int main()
{
printf("请以先序序列输入您的树(二叉树形式),并用“#”表示取消建立子树节点(例如:ABD#EG##H##CF#J##I#K###)\n");
forest T;
T=creat();
cout<<"您输入的树的广义表表示为:";
shuchu(T,visit);
printf("\n");
cout<<"树的深度为:"<<depth(T)<<endl;
}