二叉树操作
2012-11-29 21:10 Lves Li 阅读(222) 评论(0) 编辑 收藏 举报二叉树操作:
实现以二叉链表为存储结构的二叉树的创建、遍历、查找、插入和删除操作。
说明:
1、按先序遍历思想创建二叉树;
2、分别实现中序遍历和层次遍历;
3、给定元素值查找结点指针位置并返回其指针,可利用指针引用data域输出;
4、实现插入左右孩子操作,指定元素值,找到结点后若已存在对应位置的孩子结点则不插入;
5、删除指定元素值的结点,若该结点存在子树则将其子树所有结点全部删除回收;
6、程序提供简单功能菜单
// TreeTest1.cpp : 定义控制台应用程序的入口点。 // #include <iostream> using namespace std; //定义一个二叉树 数据结构 typedef struct BiTNode{ char date; //数据成员 struct BiTNode *lchild,*rchild; } biTNode,* BiTree; //定义一个队,层次遍历时用 typedef struct Dui{ char chardate; struct Dui *next; }* LDui; //判断队是否为空 bool isEmpaty(LDui D){ if (D->next==NULL){ return true; }else return false; } //入队操作 void PushDui(LDui D,char pchar){ while (D->next!=NULL){ D=D->next; } D->next=new Dui; D->next->chardate=pchar; D->next->next=NULL; } //出队函数,返回值char类型 char PopDui(LDui D){ char pchar; if(D->next!=NULL){ pchar=D->next->chardate;//吧头结点后的节点付给pchar }else { pchar='#'; return pchar; } if (D->next->next!=NULL){ D->next=D->next->next; }else { D->next=NULL; } return pchar; } //用线序遍历创建二叉树 BiTree CreateBiTree( ){ //声明一个二叉树指针类型 BiTree T; char myChar; //定义一个字符串myChar; cout<<"请输入字符"<<endl; cin >>myChar; if (myChar=='#') //如果输入‘#’表示是节点 {T=NULL; return T; } else { T=new BiTNode; //Step1.赋值根节点 T->date=myChar; //Step2.创建左子树 T->lchild=CreateBiTree( ); //Step3.创建右子树 T->rchild=CreateBiTree( ); return T; } return T; //返回指向结构体变量的指针 } //通过父节点,返回孩子节点······························ bool returnSun(BiTree T,char f,char &sun1,char &sun2){ BiTree top=T; if(T==NULL){ return false; } if(T->date!=f){ if (T->lchild!=NULL) returnSun(T->lchild, f,sun1,sun2); if (T->rchild!=NULL) returnSun(T->rchild, f,sun1,sun2); }else { //cout<<f<<" 字符已找到lelelell!"<<endl; if (T->lchild!=NULL) { //如果左孩子不为空,把其值储存到sun1中 sun1=T->lchild->date; }else { sun1='#'; } if (T->rchild!=NULL) { //如右孩子不为空,把其值储存到sun2中 sun2=T->rchild->date; }else { sun2='#'; } return true; } return false; } //层次遍历二叉树 void CengCi(BiTree T){ BiTree Top=T; LDui TopDui; TopDui=new Dui; cout<<endl<<"层次遍历二叉树: "<<endl; TopDui->next=NULL; if (T!=NULL){ //如果头结点不为空,读出头结点。 cout <<T->date<<endl; //如果左孩子不为空,入队 if (T->lchild!=NULL){ PushDui(TopDui,T->lchild->date); } //如果右孩子不为空,入队 if (T->rchild!=NULL){ PushDui(TopDui,T->rchild->date); } } //while 队不为空,出队 ,读该节点,把孩子入队 char pchar; char sun1,sun2; if (!isEmpaty(TopDui)){ while (!isEmpaty(TopDui)){ //出队 pchar=PopDui(TopDui); //找到pchar 读出它```````````````````````````` cout<<pchar<<endl; returnSun(T,pchar,sun1,sun2);//获得出队元素的左右孩子 if(sun1!='#'){//如果左孩子不为空。则入队 PushDui(TopDui,sun1); } if(sun2!='#'){//如果右孩子不为空。则入队 PushDui(TopDui,sun2); } } } } //中序遍历二叉树,参数为指向结构体变量的指针 void MidTree(BiTree Tree){ BiTree top=Tree; if(top!=NULL){ //如果节点不为空 MidTree(top->lchild); //先序遍历左子树 cout<<top->date<<endl;//输出节点数 MidTree(top->rchild);//先序遍历右子树 } } //先序遍历二叉树,参数为指向结构体变量的指针 void PreTree(BiTree Tree){ BiTree top=Tree; if(top!=NULL){ //如果节点不为空 cout<<top->date<<endl;//输出节点数 PreTree(top->lchild); //先序遍历左子树 PreTree(top->rchild);//先序遍历右子树 } } //查找节点元素 如果T中存在字符f则返回true,并打印出一句话”f 字符已找到!“。否则返回false bool findTree(BiTree T,char f){ BiTree top=T; if(T==NULL){ return false; } if(T->date!=f){ findTree(T->lchild, f); findTree(T->rchild, f); }else { cout<<f<<" 字符已找到!!!!!"<<endl; return true; } return false; } /* 插入节点元素,如果找不到要插入节点的双亲则返回false 找到结点后若已存在对应 位置的孩子结点则不插入返回false ,若找到结点后没有字节点 ,则插入节点元素返回true */ bool TreeInsert(BiTree T,char parent,char insert){ BiTree top=T; BiTNode *node; if(T==NULL){ return false; } if(T->date==parent ) { if (T->lchild!=NULL&&T->rchild!=NULL){ return false; } if (T->lchild==NULL){ node=new BiTNode; node->date=insert; node->lchild=NULL; node->rchild=NULL; T->lchild=node; cout <<"插入成功"<<endl; return true; }else if (T->rchild==NULL){ node=new BiTNode; node->date=insert; node->lchild=NULL; node->rchild=NULL; T->rchild=node; cout <<"插入成功"<<endl; return true; } } else if(T->date!=parent){ TreeInsert(T->lchild,parent,insert); TreeInsert(T->rchild,parent,insert); } return false; } //定义删除节点函数,第一个参数为指向树的指针,第二个参数为要删除的节点字符 bool delNode(BiTree T,char delchar){ if (T!=NULL){//如果跟节点不为空 if (T->date==delchar){//如果根节点为要删除的节点··· cout<<"已找到节点!!下面执行删除····"<<endl; /**/ delete T->lchild; T->lchild=NULL; delete T->rchild; T->rchild=NULL; delete T; T=new BiTNode; T->lchild=NULL; T->rchild=NULL; return true; }else if (T->lchild!=NULL&&T->lchild->date==delchar){//如果左孩子为要删除的节点 cout <<"删除左孩子:"<<endl; delete T->lchild->lchild; delete T->lchild->rchild; delete T->lchild; T->lchild=NULL; return true; }else if (T->rchild!=NULL&&T->rchild->date==delchar){//如果左孩子为要删除的节点 cout <<"删除右孩子:"<<endl; delete T->rchild->lchild; delete T->rchild->rchild; delete T->rchild; T->rchild=NULL; return true; }else { if(T->lchild!=NULL){ //如果左孩子不为空 delNode(T->lchild,delchar); } if(T->rchild!=NULL){ //如果右孩子不为空 delNode(T->rchild,delchar); } } } return false; } //定义目录函数 void Report(){ cout <<endl<<"功能菜单介绍: "<<endl; cout <<"0: 结束操作; "<<endl; cout <<"1: 先序遍历创建树; "<<endl; cout <<"2: 先序遍历树; "<<endl; cout <<"3: 层次遍历;"<<endl; cout <<"4: 中序遍历树;"<<endl; cout <<"5: 插入节点; "<<endl; cout <<"6: 删除节点;"<<endl; cout <<"7: 查找节点;"<<endl; } BiTree BTree;//定义一个全局变量 树 int ReportMethod(){ char CC; Report();//输出目录 cout <<endl<<"请输入数字:"<<endl; cin >>CC; while(CC!=0){ switch(CC){ case '0': return 0; case '1': //先序遍历创建树 BTree=CreateBiTree(); break; case '2': cout<<"先序遍历结果:"<<endl; PreTree(BTree);//调用先序遍历 break; case '3': //层次遍历 CengCi(BTree); break; case '4': cout<<"中序遍历结果:"<<endl; MidTree(BTree);//调用中序遍历 break; case '5': //插入字符 char myinsert; cout<<"输入你要插入的字符"<<endl; cin>>myinsert; cout<<"请输入你要插入字符的双亲:"<<endl; char charparent; cin >>charparent; TreeInsert(BTree,charparent,myinsert); cout<<"先序遍历结果:"<<endl; PreTree(BTree); break; case '6': //删除节点 char delchar; cout <<"请输入你要删除的节点字符:"<<endl; cin >>delchar; delNode(BTree,delchar); break; case '7': //调用查找树的节点函数 cout<<"查找字符串"<<endl; char f; cout<<"请输入你要查找的字符"<<endl; cin>>f; findTree(BTree, f); break; default : //如果输入错误 cout <<"输入错误!!!请重新输入!"<<endl; break; } Report();//输出目录 cout <<endl<<"请输入数字:"<<endl; cin >>CC; } return 0; } //主函数 int main(){ ReportMethod(); //调用函数 return 0; }