二叉树操作--数据结构
2013-11-15 21:24
274 查看
二叉树操作:
实现以二叉链表为存储结构的二叉树的创建、遍历、查找、插入和删除操作。
说明:
1、按先序遍历思想创建二叉树;
2、分别实现中序遍历和层次遍历;
3、给定元素值查找结点指针位置并返回其指针,可利用指针引用data域输出;
4、实现插入左右孩子操作,指定元素值,找到结点后若已存在对应位置的孩子结点则不插入;
5、删除指定元素值的结点,若该结点存在子树则将其子树所有结点全部删除回收;
6、程序提供简单功能菜单。
输出结果:
实现以二叉链表为存储结构的二叉树的创建、遍历、查找、插入和删除操作。
说明:
1、按先序遍历思想创建二叉树;
2、分别实现中序遍历和层次遍历;
3、给定元素值查找结点指针位置并返回其指针,可利用指针引用data域输出;
4、实现插入左右孩子操作,指定元素值,找到结点后若已存在对应位置的孩子结点则不插入;
5、删除指定元素值的结点,若该结点存在子树则将其子树所有结点全部删除回收;
6、程序提供简单功能菜单。
#include <iostream> using namespace std; //定义一个二叉树 typedef struct node { char date; //数据成员 struct node *lchild,*rchild; } BTNode,*SecondTree; //定义一个全局变量树 SecondTree seTree; //定义全局变量,用来判断是否有此亲节点; bool boolen=false; //定义一个队,层次遍历时用 typedef struct Queue { char chardate; struct Queue *next; }* LQueue; //判断队是否为空 bool isEmpaty(LQueue D); //入队操作 void PushQueue(LQueue D,char pchar); //出队函数,返回值char类型 char PopQueue(LQueue D); //通过父节点,返回孩子节点 bool returnSun(SecondTree T,char f,char &sun1,char &sun2); //层次遍历二叉树 void CengCi(SecondTree T); //中序遍历二叉树 void MidTree(SecondTree Tree); //先序遍历二叉树 void PreTree(SecondTree Tree); //创建二叉树 void CreateBTNode(BTNode *); //用先序遍历创建二叉树 //系统默认生成的广义表 //查找节点 bool findTree(SecondTree T,char f); //插入节点 bool TreeInsert(SecondTree &T,char parent,char insert); //删除节点 bool delNode(SecondTree &T,char delchar); //主菜单 void Menu(); //导航栏 int MenuMethod(); int main() { MenuMethod(); return 0; } //创建二叉树 void CreateBTNode(BTNode *) { BTNode *&T=seTree; cout<<endl<<"程序默认了一个以广义表形式构造的二叉树。无需手动输入。返回主菜单。"<<endl; char c[19]="A(B(D(,G)),C(E,F))"; BTNode*St[10],*p; int top=-1,k,j=0; char ch; T=NULL; ch=c[j]; while(ch!='\0') { switch(ch) { case '(' :top++;St[top]=p;k=1;break;//开始处理左孩子节点 case ')' :top--;break; case ',' :k=2;break;//开始处理右孩子节点 default :p=new BTNode; p->date =ch; p->lchild=p->rchild=NULL; if(T==NULL)//尚未建立根节点 { T=p;//*p为根节点 } else { switch(k) { case 1:St[top]->lchild=p;break; case 2:St[top]->rchild=p;break; } } } j++; ch=c[j]; } } //查找节点元素 如果T中存在字符f则返回true,并打印出一句话”f 字符已找到!“。否则返回false bool findTree(SecondTree T,char f) { SecondTree 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(SecondTree &T,char parent,char insert) { //SecondTree top=T; BTNode *Jnode; if(T==NULL) { return false; cout<<"二叉树为空。"<<endl; } else if(T->date==parent ) { boolen=true; if (T->lchild!=NULL&&T->rchild!=NULL) { cout<<"左右孩子节点都已经存在。无须再插入。"<<endl; return false; } else if (T->lchild==NULL) { Jnode=new node; Jnode->date=insert; Jnode->lchild=NULL; Jnode->rchild=NULL; T->lchild=Jnode; cout <<"插入左孩子节点成功"<<endl; return true; } else if(T->rchild==NULL) { Jnode=new node; Jnode->date=insert; Jnode->lchild=NULL; Jnode->rchild=NULL; T->rchild=Jnode; cout <<"插入右孩子节点成功"<<endl; return true; } } else if(T->date!=parent) { TreeInsert(T->lchild,parent,insert); TreeInsert(T->rchild,parent,insert); } return false; } //定义删除节点函数,第一个参数为指向树的指针,第二个参数为要删除的节点字符 bool delNode(SecondTree &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 node; 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 Menu(){ cout<<endl<<" 二叉树操作"<<endl; cout<<endl; cout<<"********************************************************************************"; cout <<endl<<"功能表: "<<endl<<endl; cout <<" 1: 先序遍历创建树; 2: 中序遍历树;"<<endl<<endl; cout <<" 3: 先序遍历树; 4: 层次遍历;"<<endl<<endl; cout <<" 5: 插入节点; 6: 删除节点;"<<endl<<endl; cout <<" 7: 查找节点; 8: 结束操作;"<<endl; cout<<endl<<"********************************************************************************"<<endl; } int MenuMethod() { char Cnumber; //输出目录 Menu(); cout <<endl<<"请您按键选择:"<<endl; cin >>Cnumber; while(Cnumber!=0) { switch(Cnumber) { case '1': //先序遍历创建树 CreateBTNode(seTree); break; case '2': cout<<"中序遍历结果:"<<endl; MidTree(seTree);//调用中序遍历 cout<<"返回主菜单。"<<endl; break; case '3': cout<<"先序遍历结果:"<<endl; PreTree(seTree);//调用先序遍历 cout<<"返回主菜单。"<<endl; break; case '4': //层次遍历 CengCi(seTree); cout<<"返回主菜单。"<<endl; break; case '5': //插入字符 char parent,insert; cout<<"请输入你要插入字符的双亲:"<<endl; cin>>parent; cout<<"输入你要插入的字符"<<endl; cin>>insert; TreeInsert(seTree,parent,insert); if(boolen==false) { cout<<"插入失败,不存在此双亲。,返回主菜单。"<<endl; } break; case '6': //删除节点 char delchar; cout <<"请输入你要删除的节点字符:"<<endl; cin >>delchar; delNode(seTree,delchar); cout<<"返回主菜单。"<<endl; break; case '7': //调用查找树的节点函数 char f; cout<<"请输入你要查找的字符"<<endl; cin>>f; findTree(seTree, f); break; case '8': return 0; break; default : //如果输入错误 cout <<"输入错误!!!请重新输入!"<<endl; break; } Menu();//输出目录 cout <<endl<<"请输入你的选择:"<<endl; cin >>Cnumber; } return 0; } //判断队是否为空 bool isEmpaty(LQueue D) { if (D->next==NULL) { return true; } else return false; } //入队操作 void PushQueue(LQueue D,char pchar) { while (D->next!=NULL) { D=D->next; } D->next=new Queue; D->next->chardate=pchar; D->next->next=NULL; } //出队函数,返回值char类型 char PopQueue(LQueue D) { char pchar; if(D->next!=NULL) { pchar=D->next->chardate; } else { pchar='#'; return pchar; } if (D->next->next!=NULL) { D->next=D->next->next; } else { D->next=NULL; } return pchar; } //通过父节点,返回孩子节点 bool returnSun(SecondTree T,char f,char &sun1,char &sun2) { SecondTree 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(SecondTree T) { SecondTree Top=T; LQueue TopQueue; TopQueue=new Queue; cout<<endl<<"层次遍历二叉树: "<<endl; TopQueue->next=NULL; if (T!=NULL) { //如果头结点不为空,读出头结点。 cout <<T->date<<endl; //如果左孩子不为空,入队 if (T->lchild!=NULL) { PushQueue(TopQueue,T->lchild->date); } //如果右孩子不为空,入队 if (T->rchild!=NULL) { PushQueue(TopQueue,T->rchild->date); } } //while 队不为空,出队 ,读该节点,把孩子入队 char pchar; char sun1,sun2; if (!isEmpaty(TopQueue)) { while (!isEmpaty(TopQueue)) { //出队 pchar=PopQueue(TopQueue); //找到pchar 读出它 cout<<pchar<<endl; returnSun(T,pchar,sun1,sun2);//获得出队元素的左右孩子 if(sun1!='#') {//左孩子不为空。则入队 PushQueue(TopQueue,sun1); } if(sun2!='#') {//右孩子不为空。则入队 PushQueue(TopQueue,sun2); } } } } //中序遍历二叉树 void MidTree(SecondTree Tree) { SecondTree top=Tree; if(top!=NULL) { //如果节点不为空 MidTree(top->lchild); //先序遍历左子树 cout<<top->date<<endl;//输出节点数 MidTree(top->rchild);//先序遍历右子树 } } //先序遍历二叉树,参数为指向结构体变量的指针 void PreTree(SecondTree Tree) { SecondTree top=Tree; if(top!=NULL) { //如果节点不为空 cout<<top->date<<endl;//输出节点数 PreTree(top->lchild); //先序遍历左子树 PreTree(top->rchild);//先序遍历右子树 } }
输出结果:
相关文章推荐
- 数据结构(C语言实现) - 二叉树的基本操作(建立,遍历,结点数,叶子结点数,高度,按树状打印,输出叶子结点等)
- 数据结构(27)二叉树的操作
- 数据结构——二叉树的基本操作
- 数据结构与算法学习之二叉树及二叉树的相关操作
- 数据结构——二叉树的操作
- 南邮数据结构实验6.1二叉树的基本操作
- 数据结构——c语言描述 第六章(1)二叉树树的基本操作和二叉树的线索化
- 数据结构——二叉树的插入构造和删除操作
- 数据结构.二叉树的基本操作(C语言实现)
- 数据结构之树和二叉树---二叉树的基本操作
- 数据结构—二叉树基本操作
- 数据结构——排序/搜索二叉树(非递归)的基本操作实现
- 数据结构——二叉树的基本操作
- 数据结构(十二) 二叉树的基本操作 --- 创建一个二叉树 前中后序遍历二叉树
- 数据结构——二叉树的链式存储操作集合
- 【数据结构笔记】二叉树的基本操作
- 数据结构之二叉树的简单操作
- 数据结构基础 之 树与二叉树 各类操作、思想与实现
- C++数据结构之二叉树非递归操作
- 数据结构——二叉树的基本操作