急!高分悬赏!求c语言高手!!!二叉树输入中如何判断输入是不是合法?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了急!高分悬赏!求c语言高手!!!二叉树输入中如何判断输入是不是合法?相关的知识,希望对你有一定的参考价值。
如:input:a0; output:invalid!
input:a00;output:valid!
input:ab000;output:valid!
input:ab000c0;output:invalid!
(0是二叉树的虚节点,用前序来创建排列输入的字符串)
以下是我用的部分代码,但如果输入不合法的,如果是遗漏虚节点的(如:a0)运行时候就没反应,如果是有多余的节点的(如:ab000c0),程序直接忽略了运行。
typedef struct Binnode
char data;
struct Binnode *lchild;
struct Binnode *rchild;
Binnode,*Bintree ;
char ch;
if((ch=getchar())=='0')
*root=NULL;
else
*root=(Bintree)malloc(sizeof(Binnode));
(*root)->data=ch;
Creat_Bintree(&(*root)->lchild);
Creat_Bintree(&(*root)->rchild);
2. 初始,平衡二叉树为空树,可以按先序输入平衡二叉树,以输入0结束,中间以回车隔开,创建好二叉树后,可以对其查找,再对其插入,输入0结束插入,再可以对其删除,输入0结束,每次插入或删除一个结点后,更新平衡二叉树的显示。
3. 本程序以用户和计算机的对话方式执行,根据计算机终端显示:“提示信息”下,用户可由键盘输入要执行的操作。
4. 测试数据(附后)
二、 概要设计
1. 抽象数据类型动态查找表的定义如下:
ADT DynamicSearchTable
数据结构D:D是具有相同特性的数据元素的集合。各个数据元素含有类型相同,可惟一标识数据元素的关键字。
数据关系R:数据元素同属一个集合。
基本操作P:
InitDSTable(&DT);
操作结果:构造一个空的动态查找表DT。
DestroyDSTable(&DT);
初试条件:动态查找表DT存在。
操作结果: 销毁动态查找表DT。
SearchDSTable(DT,key);
初试条件:动态查找表DT存在,key为和关键字类型相同的给定值。
操作结果: 若DT中存在其关键字等于key的数据元素,则函数值为该元素的值或表中的位置,否则为“空”。
InsertDSTable(&DT,e);
初试条件:动态查找表DT存在,e为待插入的数据元素。
操作结果: 若DT中不存在其关键字等于e. key的数据元素,则插入e到DT。
DeleteDSTable(&DT,key);
初试条件:动态查找表DT存在,key为和关键字类型相同的给定值。
操作结果: 若DT中存在其关键字等于key的数据元素,则删除之。
TraverseDSTable(DT,Visit());
初试条件:动态查找表DT存在,Visit()是结点操作的应用函数。
操作结果: 按某种次序对DT的每个结点调用函数Visit()一次且至多
一次。一但Visit()失败,则操作失败。
ADT DynamicSearchTable
2. 本程序包含两个模块:
Void main()
Do
接受命令(根据提示输入终点城市和起点城市的序号);
处理命令;
while(“命令”=“退出”);
3.本程序只有两个模块,调用关系简单
主程序模块
平衡二叉树的模块
三、 详细设计
1. 根据题目要求和查找的基本特点,其结点类型
typedef struct BSTnode
int data;
int bf;
struct BSTnode *lchild,*rchild;
BSTnode,*bstree;
#define LH +1
#define EH 0
#define RH -1
/-----------------------------************对平衡二叉树的操作
bstree InsertAVL(bstree &T, int e);
////////在平衡二叉树中插入结点。
int FindAVL(bstree p,int e);
////////查找平衡二叉树中是否有结点e。
bstree DeleteAVL(bstree &T,int e)
////////删除平衡平衡二叉树的结点e,并保持平衡二叉树的性质。
int Preordertraverse(bstree T)
////////按先序遍历平衡二叉树。
/------------------------************平衡二叉树的操作的详细算法
bstree InsertAVL(bstree &T, int e)
bstree p;
//插入新结点,树长高置taller为TRUE
if(!T)
T=(bstree)malloc(sizeof(BSTnode));
T->data=e;
T->lchild=T->rchild=NULL;
T->bf=EH;
taller=TRUE;
else
//树中存在和e有相同关键字的结点则不再插入
if(e==T->data)
taller=FALSE;
return NULL;
//值小于则继续在树的左子树中搜索
if(e < T->data)
//插入到左子树且左子树长高
p=InsertAVL(T->lchild,e);
if(p)
T->lchild=p;
if(taller)
switch(T->bf) //检查*T的平衡度
case LH: //原本左子树比右子树高,需要做左平衡处理
T=LeftBalance(T);
taller=FALSE;
break;
case EH: //原本左子树和右子树同高,现因左子树争高而使树增高
T->bf=LH;
taller=TRUE;
break;
case RH: //原本右子树比左子树高,现在左右子树等高
T->bf=EH;
taller=FALSE;
break;
///////switch(T->bf)
///////if(taller)
/////if(p)
///////if(e < T->data)
//继续在*T的右子树中搜索
else
//插入到右子树且使右子树长高
p=InsertAVL(T->rchild,e);
if (p)
T->rchild=p;
if(taller)
switch(T->bf) //检查*T的平衡度
case LH: //原本左子树比右子树高,现在左右子树等高
T->bf=EH;
taller=FALSE;
break;
case EH: //原本左子树和右子树同高,现因右子树增高而使树增高
T->bf=RH;
taller=TRUE;
break;
case RH: //原本右子树比左子树高,需要做右平衡处理
T=RightBalance(T);
taller=FALSE;
break;
//////switch(T->bf)
/////if(taller)
/////if (p)
//////if(e > T->data)
///////else
return T;
int Preordertraverse(bstree T)
if(T)
printf(" %d %d\n",T->data,T->bf);
Preordertraverse(T->lchild);
Preordertraverse(T->rchild);
return 1;
int FindAVL(bstree p,int e)
if(p==NULL)return NULL;
else if(e==p->data) return true;
else if(e<p->data)
p=p->lchild;
return FindAVL(p, e);
////左子树上查找
else
p=p->rchild;
return FindAVL( p, e);
////右子树上查找
bstree DeleteAVL(bstree &T,int e)
//删除后要保证该二叉树还是平衡的
int n,m=0;/////标记
bstree q;
if(!T)return NULL;
else
if(e==T->data) ////直接删除
n=Delete(T,e);
m=n;
if(m!=0)
q=T;
DeleteAVL(T,m);
q->data=m;
else
if(e<T->data)////在左子树上寻找
DeleteAVL(T->lchild,e);
if(shorter)
switch(T->bf)
case LH:T->bf=EH;shorter=true;break;
case EH:T->bf=RH;shorter=false;break;
case RH:Delete_Rightbalance(T);shorter=true;break;
////switch(T->bf)
/////if(shorter)
/////if(e<T->data)
else /////////在右子树上寻找
DeleteAVL(T->rchild,e);
if(shorter)
switch(T->bf)
case LH:Delete_Leftbalance(T);shorter=true;break;
case EH:T->bf=LH;shorter=false;break;
case RH:T->bf=EH;shorter=true;break;
////////switch(T->bf)
////////在右子数上寻找完
////////在左右子上完
///////////删除完
return T;
2. 主程序和其他伪码算法
void main()
while(e!=0)
if(e!=0) InsertAVL(T,e);
while(d!=0)
if(d!=0) InsertAVL(T,d);
Preordertraverse(T);
c=FindAVL(T,t);
if(c==1)printf("有要查找的节点\n");
else printf("无要查找的节点\n");
do
DeleteAVL(T,b);
Preordertraverse(T);
while(b==1);
///右旋
bstree R_Rotate(bstree &p)
bstree lc;
lc=p->lchild;
p->lchild=lc->rchild;
lc->rchild=p;
p=lc;
return p;
////左旋
bstree L_Rotate(bstree &p)
bstree rc;
rc=p->rchild;
p->rchild=rc->lchild;
rc->lchild=p;
p=rc;
return p;
/////左平衡处理
bstree LeftBalance(bstree &T)
bstree lc,rd;
lc=T->lchild; //lc指向*T的左子树根结点
switch(lc->bf) //检查*T的左子树平衡度,并做相应的平衡处理
case LH: //新结点插入在*T的左孩子的左子树上,要做单右旋处理
T->bf=lc->bf=EH;
T=R_Rotate(T);
break;
case RH: //新结点插入在*T的左孩子的右子树上,要做双旋处理
rd=lc->rchild; //rd指向*T的左孩子的右子树根
switch(rd->bf) //修改*T及其左孩子的平衡因子
case LH:
T->bf=RH;
lc->bf=EH;
break;
case EH:
T->bf=lc->bf=EH;
break;
case RH:
T->bf=EH;
lc->bf=LH;
break;
//////////switch(rd->bf)
rd->bf=EH;
T->lchild=L_Rotate(T->lchild); //对*T的左孩子做左旋平衡处理
T=R_Rotate(T); //对*T做右旋处理
////////switch(lc->bf)
return T;
////右平衡处理
bstree RightBalance(bstree &T)
bstree rc,ld;
rc=T->rchild; //rc指向*T的右子树根结点
switch(rc->bf) //检查*T的右子树平衡度,并做相应的平衡处理
case RH: //新结点插入在*T的右孩子的右子树上,要做单右旋处理
T->bf=rc->bf=EH;
T=L_Rotate(T);
break;
case LH: //新结点插入在*T的右孩子的左子树上,要做双旋处理
ld=rc->lchild; //ld指向*T的右孩子的左子树根
switch(ld->bf) //修改*T及其右孩子的平衡因子
case LH:
T->bf=EH;
rc->bf=RH;
break;
case EH:
T->bf=rc->bf=EH;
break;
case RH:
T->bf=LH;
rc->bf=EH;
break;
///switch(ld->bf)
ld->bf=EH;
T->rchild=R_Rotate(T->rchild); //对*T的右孩子做右旋平衡处理
T=L_Rotate(T); //对*T做左旋处理
/////switch(rc->bf)
return T;
int Delete(bstree &T,int e)
//删除结点
bstree p,q;
e=0;
p=T;
if(!T->rchild) //右子数为空需要重接它的左子数
T=T->lchild;
free(p);
shorter=true;
else if(!T->lchild) //重接它的右子数
T=T->rchild;
free(p);
shorter=true;
else //左右子数均不空
q=T->lchild;
while(q->rchild!=NULL)//转左,然后向右到尽头
q=q->rchild;
e=q->data;
return e;
void Delete_Rightbalance(bstree &T)
///////////删除在左子树上的,相当于插入在右子树
bstree rc=T->rchild,ld;
switch(rc->bf)
case LH://///////双旋 ,先右旋后左旋
ld=rc->lchild;
rc->lchild=ld->rchild;
ld->rchild=rc;
T->rchild=rc->lchild;
rc->lchild=T;
switch(ld->bf)
case LH:T->bf=EH;
rc->bf=RH;
break;
case EH:T->bf=rc->bf=EH;
break;
case RH:T->bf=LH;
rc->bf=EH;
break;
ld->bf=EH;
T=rc;
shorter=true;break;
case EH:///////删除在左子树,相当于插入在右子树,左单旋
T->rchild=rc->lchild;
rc->lchild=T;
rc->bf=LH;
T->bf=RH;
T=rc;
shorter=EH;break;
case RH:///////删除在左子树,相当于插入在右子树,左单旋
T->rchild=rc->lchild;
rc->lchild=T;
rc->bf=T->bf=EH;
T=rc;
shorter=true;break;
void Delete_Leftbalance(bstree &T)/////删除右子树上的,相当于插入在左子树上
bstree p1,p2;
p1=T->lchild;
switch(p1->bf)
case LH:T->lchild=p1->rchild;//////右旋
p1->rchild=T;
p1->bf=T->bf=EH;
T=p1;
shorter=true;
break;
case EH:T->lchild=p1->rchild;///////右旋
p1->rchild=T;
p1->bf=RH;
T->bf=LH;
T=p1;
shorter=false;
break;
case RH:p2=p1->rchild;//////////右双旋
p1->rchild=p2->lchild;
p2->lchild=p1;
T->lchild=p2->rchild;
p2->rchild=T;
switch(p2->bf)
case LH:T->bf=RH;p1->bf=EH;break;
case EH:T->bf=EH;p1->bf=EH;break;
case RH:T->bf=EH;p1->bf=LH;break;
p2->bf=EH;
T=p2;
shorter=true;break;
3. 函数的调用关系图
Main
InsertAVL Preordertraverse FindAVL DeleteAVL
四、 调试分析
1. 在开始对平衡二叉树的插入后,再做平衡处理时,特别是在做双向旋转平衡处理后的更新时,费了一些时间;
2. 在做平衡二叉树的删除时,当删除结点左右孩子均在时,开始直接用左子树的最大数代替,然后直接删除结点,结果导致删除了将要删除的结点及其孩子均删除了,后来将要删除的结点用左子树的最大树代替后,对左子树的最大结点做好标记,然后再做对其做删除处理。
3. 本程序算法基本简单,没有多大困难,就是在分析做双旋平衡处理的更新时,开始思路有些混乱,后来就好了;
五、 用户手册
1. 本程序的运行环境为DOS操作系统,执行文件为Balanced Tree.exe。
2. 进入演示程序后,按广度遍历输入平衡二叉树,中间以回车键隔开,输入0为结束;再输入要插入的结点,输入0结束,再输入要查找的结点,最后可以输入要删除的结点,输入0结束
六、 测试结果
先按广度遍历创建平衡二叉树(亦可一个一个的插入二叉树的结点)(50 20 60 10 30 55 70 5 15 25 58 90) ,输入0结束,然后可插入结点(39),其会显示插入后的二叉树,输入0,不再插入;输入要查找结点(6),输入要删除的结点(20),其显示如下:
/*****自己做完截图放在这里*****/
七、 附录
Balance Tree.cpp
有两个分号是中文的,还有头文件自己加,其他没有问题
另外,站长团上有产品团购,便宜有保证 参考技术A 设置一个char a[]来保存输入的Input
然后遍历数组a[],直到strlen
根据a[]里面的字符进行判断.
如果第一个是0,则检测是否后面有不是0的字符,如果有,就是invalid
如果第一个不是0,检测第二个,如果第二个为0,检测第三个,如果第三个不为0,输出invalid
如果第一个不是0,检测第二个,如果第二个不为0,检测第三个等等,不断循环追问
但是作业里说input字符串最长可达1000
未知长度的字符串怎么检测呢?
其实就是个循环,根据前序来看:第一个,第二个,第三个分别为根,左,右,那如果根为0,左不为零,那就结束了,invalid。同理,左为0,右不为0,同样invalid。
追问解决了!谢谢给的提示!我是这样做的:
if ((i == 1) && (ch[0] == '0')) //i是输入字符串的长度,ch是字符串;第一种情况只有一个零的;
return 1;
if ((i%2 != 1)||(ex != in + 1)||((ch[i-1] != '0') && (ch[i-2] != '0')) ) //如果字符长度不为单数,或0不等于除0之外结点加一(虚节点等于所有结点加一),或最后两个字符不都是0的都是不合法的
printf("invalid!\n");
return 0;
else
return 1;
急!二叉树的存储结构,并完成:建立、查找、计算结点数、求高度、三种遍历方式
不要和别人雷同!
public class BinaryTree<E> //二叉树类protected BinaryNode<E> root; //根结点
public BinaryTree() //构造空二叉树
root=null;
public BinaryTree(BinaryNode<E> root) //构造指定根结点的二叉树
this.root=root;
public boolean isEmpty() //判断是否空二叉树
return this.root==null;
public BinaryNode<E> getRoot() //返回二叉树的根结点
return this.root;
//6.3.3 二叉树的遍历
public void preOrder() //先根次序遍历二叉树
System.out.print("\n先根序列: ");
preOrder(root);
private void preOrder(BinaryNode<E> p) //先根次序遍历以p结点为根的子二叉树
if(p!=null) //若二叉树不空
System.out.print(p.data+" "); //访问当前结点
preOrder(p.left); //按先根次序遍历当前结点的左子树
preOrder(p.right); //按先根次序遍历当前结点的右子树
public void inOrder() //中根次序遍历二叉树
System.out.print("\n中根序列: ");
inOrder(root);
private void inOrder(BinaryNode<E> p) //中根次序遍历以p结点为根的子二叉树
if (p!=null)
inOrder(p.left); //中根次序遍历左子树
System.out.print(p.data+" ");
inOrder(p.right); //中根次序遍历右子树
public void postOrder() //后根次序遍历二叉树
System.out.print("\n后根序列: ");
postOrder(root);
private void postOrder(BinaryNode<E> p) //后根次序遍历以p结点为根的子二叉树
if (p!=null)
postOrder(p.left);
postOrder(p.right);
System.out.print(p.data+" ");
//【例6.1】 构造并遍历二叉树。
//3. 基于遍历的操作
public int count() //求一棵二叉树中所有结点个数
return count(root);
public int count(BinaryNode<E> p) //求以p结点为根的子树的结点个数
if (p!=null)
return 1+count(p.left)+count(p.right);
else
return 0;
public int depth() //求二叉树的深度
return depth(root);
public int depth(BinaryNode<E> p) //求以p结点为根的子树的深度,后根次序遍历
if (p!=null)
int ld = depth(p.left); //求左子树的深度
int rd = depth(p.right);
return (ld>=rd) ? ld+1 : rd+1;
return 0;
public BinaryNode<E> search(E value) //查找值为value的结点
return search(root, value);
public BinaryNode<E> search(BinaryNode<E> p, E value) //在以p为根的子树中查找值为value的结点
//先根次序遍历,返回查找到结点,若未找到返回null
BinaryNode<E> find=null; //记载找到结点
if (p!=null && value!=null)
if (p.data.equals(value))
find = p; //查找成功
else
find = search(p.left, value); //在左子树中查找
if (find==null)
find=search(p.right, value); //若左子树中未找到,则继续在右子树中查找
return find; //返回找到结点
public BinaryNode<E> getParent(BinaryNode<E> node) //返回指定结点node的父母结点
//若空树、未找到或node为根,返回null
if (root==null || node==null || node==root)
return null;
return getParent(root, node);
public BinaryNode<E> getParent(BinaryNode<E> p, BinaryNode<E> node)
//在以p为根的子树中查找并返回node结点的父母结点
BinaryNode<E> find=null; //记载找到结点
if (p!=null)
if (p.left==node || p.right==node)
find = p; //查找成功
else
find = getParent(p.left, node); //在左子树中查找
if (find==null)
find = getParent(p.right, node); //若左子树中未找到,则继续在右子树中查找
return find; //返回找到的父母结点
//6.3.4 构造二叉树
// 1、以先根、中根次序遍历序列建立二叉树
public BinaryTree(String prestr,String instr) //1、以先根、中根次序遍历序列建立二叉树
root=create(prestr,instr);
//root=create2(prestr,instr);
public BinaryNode create(String prestr, String instr)
BinaryNode<String> p=null;
int k,n;
String first,presub,insub;
n=prestr.length();
if(n>0)
System.out.print("prestr="+prestr+"\t instr="+instr);
first=prestr.substring(0,1);
p=new BinaryNode<String>(first);
k=instr.indexOf(first);
System.out.println("\t first="+first+"\t k="+k);
presub=prestr.substring(1,k+1);
insub=instr.substring(0,k);
p.left=create(presub,insub);
presub=prestr.substring(k+1,n);
insub=instr.substring(k+1,n);
p.right=create(presub,insub);
return p;
public BinaryNode create2(String instr, String poststr) //以中根、后根次序遍历序列建立二叉树
BinaryNode<String> p=null;
int k,n;
String last,postsub,insub;
n=poststr.length();
if(n>0)
System.out.print("instr="+instr+"\t poststr="+poststr);
last=poststr.substring(poststr.length()-1,poststr.length());
p=new BinaryNode<String>(last);
k=instr.indexOf(last);
System.out.println("\t last="+last+"\t k="+k);
postsub=poststr.substring(0,k);
insub=instr.substring(0,k);
p.left=create2(insub,postsub);
postsub=poststr.substring(k,n-1);
insub=instr.substring(k+1,n);
p.right=create2(insub,postsub);
return p;
// 2、以标明空子树的先根序列构造一棵二叉树
public BinaryTree(E[] preorder) //2、以标明空子树的先根序列构造一棵二叉树
root=create(preorder);
private int i=0;
private BinaryNode<E> create(E[] preorder) //创建一棵子树,当前结点值是preorder[i]
//返回所创建子树的根结点
BinaryNode<E> p = null;
if (i<preorder.length)
E elem=preorder[i];
i++;
if (elem!=null)
p = new BinaryNode<E>(elem); //建立p结点
p.left = create(preorder); //建立p的左子树
p.right = create(preorder); //建立p的右子树
return p;
// 3、以广义表表示建立二叉树
public BinaryTree(String GenListStr)
System.out.println("GenListStr="+GenListStr);
if(GenListStr.length()>0)
root=create(GenListStr); //以GenListStr的全部元素建立一棵二叉树
public BinaryNode create(String GenListStr) //以GenListStr的部分元素(从i开始)建立一棵子树
BinaryNode p=null;
char ch=GenListStr.charAt(i);
if(ch>='A' && ch<='Z') //大写字母
p=new BinaryNode<String>(ch+""); //建立结点
i++; //跳过大写字母
ch=GenListStr.charAt(i);
if(ch=='(')
i++; //跳过(
p.left=create(GenListStr); //建立左子树
i++; //跳过#
p.right=create(GenListStr); //建立右子树
i++; //跳过)
if(ch=='#')
i++; //跳过#
return p; //ch非大写字母时,返回null
//【例6.2】 输出二叉树中指定结点的所有祖先结点。
//6.3.5 二叉树的插入和删除操作
public void insert(BinaryNode<E> p, E element, boolean leftChild) //插入元素element作为p结点的孩子
//若leftChild为true,插入结点作为左孩子,否则作为右孩子
if (p!=null)
BinaryNode<E> q = new BinaryNode<E>(element);
if (leftChild)
q.left = p.left; //p结点的原左孩子成为q结点的左孩子
p.left = q; //q结点作为p结点的左孩子
else
q.right = p.right; //p结点的原右孩子成为q结点的右孩子
p.right = q; //q结点作为p结点的右孩子
public void insert(BinaryNode<E> p, E element) //插入元素element作为p结点的左孩子
insert(p, element, true);
public void remove(BinaryNode<E> p, boolean leftChild) //删除p结点的左/右子树
//若leftChild为true,删除左子树,否则删除右子树
if (p!=null)
if (leftChild)
p.left = null;
else
p.right = null;
public void remove(BinaryNode<E> p) //删除p结点的左子树
remove(p, true);
//6.3.6 二叉树遍历的非递归算法
public void preOrderTraverse() //先根次序遍历二叉树的非递归算法
System.out.print("先根次序遍历(非递归): ");
LinkedStack<BinaryNode<E>> stack = new LinkedStack<BinaryNode<E>>(); //创建一个空栈
BinaryNode<E> p = this.root;
while(p!=null || !stack.isEmpty()) //p非空或栈非空时
if(p!=null)
System.out.print(p.data+" "); //访问结点
stack.push(p); //p结点入栈
p=p.left; //进入左子树
else //p为空且栈非空时
p=stack.pop(); //p指向出栈结点
p=p.right; //进入右子树
System.out.println();
public void inOrderTraverse() //中根次序遍历二叉树的非递归算法
System.out.print("中根次序遍历(非递归): ");
LinkedStack<BinaryNode<E>> stack = new LinkedStack<BinaryNode<E>>(); //创建一个空栈
BinaryNode<E> p = this.root;
while(p!=null || !stack.isEmpty()) //p非空或栈非空时
if(p!=null)
stack.push(p); //p结点入栈
p=p.left; //进入左子树
else //p为空且栈非空时
p=stack.pop(); //p指向出栈结点
System.out.print(p.data+" "); //访问结点
p=p.right; //进入右子树
System.out.println();
//后根次序未写
//6.3.7 二叉树的层次遍历
public void levelOrder() //按层次遍历二叉树
LinkedQueue<BinaryNode<E>> que=new LinkedQueue<BinaryNode<E>>(); //创建一个空队列
BinaryNode<E> p=this.root;
System.out.print("层次遍历: ");
while(p!=null)
System.out.print(p.data+ " ");
if(p.left!=null)
que.enqueue(p.left); //p的左孩子结点入队
if(p.right!=null)
que.enqueue(p.right); //p的右孩子结点入队
p = que.dequeue(); //p指向出队结点
System.out.println();
//第6章习题
public void leaf() //遍历输出叶子结点
leaf(root);
private void leaf(BinaryNode<E> p) //先根次序遍历,输出叶子结点,3种遍历次序结果一样
if(p!=null)
if (p.isLeaf())
System.out.print(p.data+" ");
leaf(p.left);
leaf(p.right);
public int countLeaf() //求一棵二叉树中所有叶子结点个数
return countLeaf(root);
private int countLeaf(BinaryNode<E> p) //求以p结点为根的子树的叶子结点个数
if (p==null)
return 0;
if (p.isLeaf())
return 1;
return countLeaf(p.left)+countLeaf(p.right);
public BinaryTree(BinaryTree<E> bitree) //以已知的bitree构造二叉树
this.root = copy(bitree.root);
private BinaryNode<E> copy(BinaryNode<E> p) //复制以p根的子二叉树
BinaryNode<E> q = null;
if(p!=null)
q = new BinaryNode<E>(p.data);
q.left = copy(p.left); //复制左子树
q.right = copy(p.right); //复制右子树
return q; //返回建立子树的根结点
public boolean equals(Object obj) //比较两棵二叉树是否相等
if (obj == this)
return true;
if (obj instanceof BinaryTree)
BinaryTree<E> bitree = (BinaryTree)obj;
return equals(this.root, bitree.root);
return false;
private boolean equals(BinaryNode<E> p, BinaryNode<E> q) //判断以p和q结点为根的两棵子树是否相等
//递归方法
if(p==null && q==null)
return true;
if(p!=null && q!=null)
return (p.data.equals(q.data)) && equals(p.left, q.left) && equals(p.right, q.right);
return false;
public boolean replace(E old, E value) //将首次出现的值为old结点值替换为value
BinaryNode<E> find=search(old); //查找值为old的结点
if(find!=null)
find.data = value; //替换结点元素值
return find!=null;
public void replaceAll(E old, E value) //将值为old的结点全部替换为value
replaceAll(root, old, value);
private void replaceAll(BinaryNode<E> p, E old, E value) //在以p为根的子树中实现全部替换
if(p!=null)
if(p.data.equals(old))
p.data = value;
replaceAll(p.left, old, value);
replaceAll(p.right, old, value);
public static void main(String args[])
String[] preorder = "A","B","D",null,"G",null,null,null,"C","E",null,null,"F","H";
BinaryTree<String> bitree = new BinaryTree<String>(preorder);
preorder[0]="Z";
bitree.preOrder();
bitree.inOrder();
bitree.postOrder();
System.out.println("\n结点个数: "+bitree.count());
System.out.println("高度: "+bitree.depth());
System.out.print("叶子结点: ");
bitree.leaf();
System.out.println(" , 共"+bitree.countLeaf()+"个");
BinaryTree<String> bitree2 = new BinaryTree<String>(bitree);
System.out.println("两棵二叉树相等? "+bitree.equals(bitree2));
System.out.println("第2棵二叉树替换(\"D\",\"F\"): "+bitree2.replace("D","F"));
System.out.println("两棵二叉树相等? "+bitree.equals(bitree2));
System.out.println("第2棵二叉树全部替换(\"F\",\"Y\") ");
bitree2.replaceAll("F","Y");
bitree2.preOrder();
BinaryNode<String> find = bitree.search("D"); //查找
bitree.insert(find, "Z");
System.out.println("插入Z作为 "+find.data+" 的左孩子\n");
bitree.levelOrder();
bitree.preOrderTraverse();
bitree.inOrderTraverse();
String[] preorder2 = "A","B",null,null,"C"; //标明空子树的先根序列
BinaryTree<String> bitree3 = new BinaryTree<String>(preorder2);
bitree3.preOrder();
bitree3.inOrder();
bitree3.postOrder();
/*
BinaryTree<String> bitree4 = new BinaryTree<String>(preorder2);
bitree4.root = bitree4.create(preorder2); //错,i越界,私有化可避免问题
bitree4.preOrder();
*/
String[] preorder3 = "D","B","A",null,null,"C",null,null,"E"; //二叉排序树
BinaryTree<String> bitree5 = new BinaryTree<String>(preorder3);
bitree5.inOrder();
System.out.println("\n二叉排序树? "+bitree5.isSorted());
//第8章习题
public boolean isSorted() //判断一棵二叉树是否为二叉排序树
return isSorted(this.root);
public boolean isSorted(BinaryNode<E> p)
boolean yes = true;
if (p!=null)
if (!(p.data instanceof Comparable))
return false;
Comparable cmpobj = (Comparable)p.data;
if ((p.left==null || p.left!=null && cmpobj.compareTo(p.left.data)>0) &&
(p.right==null || p.right!=null && cmpobj.compareTo(p.right.data)<0))
yes = isSorted(p.left);
if (yes)
yes = isSorted(p.right);
else
yes = false;
return yes;
/*
程序运行结果如下:
先根序列: A B D G C E F H
中根序列: D G B A E C H F
后根序列: G D B E H F C A
结点个数: 8
高度: 4
叶子结点: G E H , 共3个
两棵二叉树相等? true
第2棵二叉树替换("D","F"): true
两棵二叉树相等? false
第2棵二叉树全部替换("F","Y")
先根序列: A B Y G C E Y H
第1棵二叉树查找: D
层次遍历: A B C D E F Z G H
先根次序遍历(非递归): A B D Z G C E F H
中根次序遍历(非递归): Z D G B A E C H F
先根序列: A B D G C E F H
中根序列: D G B A E C H F
后根序列: G D B E H F C A
中根序列: A B C D E
二叉排序树? true
*/
这是二叉树的所有方法 及实现实例
还有就是需要建立节点类 你应该知道怎么建的吧 参考技术A /*
包括二叉树的创建和遍历
*/
//头文件
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
//预定义宏常量
#define OK 1
#define ERROR -1
#define ENDFLAG '#'
typedef char TelemType;
typedef int status;
//二叉树的存储结构
typedef struct BiTNode
TelemType data;
struct BiTNode *lchild,*rchild;
BiTNode,*BiTree;
//全局变量,表示叶子个数
int m=0;
//二叉树的创建
status CreateBiTree(BiTree *T)
// 先序创建
TelemType ch;
scanf("%c",&ch);
if(ch==ENDFLAG) *T=NULL;
else
if(!(*T=(BiTNode *)malloc(sizeof(BiTNode))))
printf("\nOut of space.");
getch();
exit(0);
(*T)->data=ch; //生成根结点
CreateBiTree(&((*T)->lchild));//左子树
CreateBiTree(&((*T)->rchild));//右子树
return OK;
//先序遍历
status PreOrderTraverse(BiTree T)
if(T)
printf("%c",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
return OK;
/*
//中序
status InOrderTraverse(BiTree T)
if(T)
InOrderTraverse(T->lchild);
printf("%c",T->data);
InOrderTraverse(T->rchild);
return OK;
//后序
status PostOrderTraverse(BiTree T)
if(T)
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c",T->data);
return OK;
*/
/*
用队列 层次遍历
*/
//存储定义
typedef char QElemType;
//typedef int status;
typedef struct Queue
QElemType data;
struct Queue *next;
Queue;
//头指针和尾指针
typedef struct
Queue *front;
Queue *rear;
LinkQueue;
//初始化队列
status InitQueue(LinkQueue *q)
q->front=q->rear =NULL; //----无头结点
return OK;
/*判断队列是否为空*/
status QueueEmpty(LinkQueue *Q)
return (Q->front==NULL)&&(Q->rear==NULL);
/*实际上只须判断队头指针是否为空即可*/
//入队
void EnQueue(LinkQueue *q,QElemType e)
Queue *p;
p=(Queue *)malloc(sizeof(Queue));/*申请新结点*/
p->data=e;
p->next=NULL;
if(QueueEmpty(q))
q->front=q->rear=p;
else /*x插入非空队列的尾*/
q->rear->next=p; /*p链到原队尾结点后*/
q->rear=p;/*队尾指针指向新的尾*/
//出队
QElemType DeQueue(LinkQueue *q)
Queue *p;
QElemType e;
if(QueueEmpty(q))
printf("Queue underflow\n");/*下溢*/
exit(1) ;
p=q->front;/*指向对头结点*/
e=p->data;/*保存对头结点的数据*/
q->front=p->next;/*将对头结点从链上摘下*/
if(q->rear==p)/*原队中只有一个结点,删去后队列变空,此时队头指针已为空*/
q->rear=NULL;
free(p);/*释放被删队头结点*/
return e;/*返回原队头数据*/
/*层次遍历思想 递归
a.根结点入队列
b.原队左子树的左右孩子(非空)入队列
c.原队右子数的左右孩子(非空)入队列
*/
//层次遍历入队列
status Arrange(BiTree T,LinkQueue *Q)
if(T)
EnQueue(Q,T->data);
Arrange(T->lchild,Q);
Arrange(T->rchild,Q);
return OK;
//从队列中输出各元素
status ArrangementTraverse(BiTree T)
char e;
LinkQueue Q;
InitQueue(&Q);
if(T)
Arrange(T,&Q);//递归调用
while(!QueueEmpty(&Q))
e=DeQueue(&Q);
printf("%c",e);
return OK;
//求二叉树的叶结点个数
status NumberLeaves(BiTree T)
//先序遍历得到叶结点的数目
//m=0;
if(T)
if(T->lchild==NULL&&T->rchild==NULL) m++;
NumberLeaves(T->lchild);
NumberLeaves(T->rchild);
return OK;
int btnodeheight(BiTree b)
int lchildh,rchildh;
if (b==NULL) return(0);
else
lchildh=btnodeheight(b->lchild);
rchildh=btnodeheight(b->rchild);
return (lchildh>rchildh)? (lchildh+1):(rchildh+1);
/*
//一个比较函数
status Max(int m, int n)
if (m > n)
return m;
else
return n;
//获取二叉树的高度
status HighBitree(BiTree t)
if (t == NULL)
return 0;
else
return 1 + Max(HighBitree(t->lchild), HighBitree(t->rchild));
*/
//主函数
void main()
BiTree T;
printf("请创建二叉树:\n");
CreateBiTree(&T);
NumberLeaves(T);
printf("叶节点个数为:");
printf("%d",m);
printf("\n二叉树的高度为:");
printf("%d",btnodeheight(T));
// printf("%d",HighBitree(T));
printf("\n先序遍历:\n");
PreOrderTraverse(T);
/* printf("\n中序遍历:\n");
InOrderTraverse(T);
printf("\n后序遍历:\n");
PostOrderTraverse(T);*/
printf("\n层次遍历\n");
ArrangementTraverse(T);
printf("\n");
参考技术B 发给你了注意查收
以上是关于急!高分悬赏!求c语言高手!!!二叉树输入中如何判断输入是不是合法?的主要内容,如果未能解决你的问题,请参考以下文章
求C语言高手! 1:用动画演示二叉树的三种遍历。2:绘制出一个小球,在屏幕左右端之间不停滚动。