二叉树操作:
实现以二叉链表为存储结构的二叉树的创建、遍历、查找、插入和删除操作。
说明:
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;
}