主要功能:输出二叉树、计算二叉树高度、查找节点是否存在、输出所有叶子结点、计算叶子节点个数、前序遍历输出二叉树、中序遍历输出二叉树 、后序遍历输出二叉树、计算结点个数、输出该树中结点最大值 、输出树中结点值为x的层、输出左右孩子结点值 、计算二叉树的各层的宽度、计算指定结点所在的层次、销毁释放二叉树 、先序非递归算法 、中序非递归算法 、后序非递归算法 、层次遍历(队列)算法
#include <fstream>
#include<iostream>
#include<stdlib.h>
#define MaxSize 100
using namespace std;
typedef char ElemType;
typedef struct node{
ElemType data;
struct node *lchild,*rchild;//二叉树结构声明
}BTNode;
typedef struct
{ BTNode *data[100]; //存放栈中的数据元素
int top; //存放栈顶指针,即栈顶元素在data数组中的下标
} SqStack;
typedef struct
{
BTNode *data[MaxSize];//存放队中元素
int front,rear;//队头队尾指针
}SqQueue;
int width[10] = {0}; //存放各层宽度的数组
void TreeWidth(BTNode *b){
int depth = 0; //遍历的层
if (b== NULL){
return;
}
if (depth == 0) {
width[0] = 1;
}
if (b->lchild!= NULL) {
width[++depth] ++;
printf("往左子树,当前在第%d层,当前计算的宽度为%d\n",depth,width[depth]);
TreeWidth(b->lchild);
}
if (b->rchild!= NULL) {
width[++depth] ++;
printf("往右子树,当前在第%d层,当前计算的宽度为%d\n",depth,width[depth]);
TreeWidth(b->rchild);
}
depth--;
printf("返回上一层,当前在第%d层,当前计算的宽度为%d\n",depth,width[depth]);
}
BTNode *LchildNode(BTNode *p) /*返回*p结点的左孩子结点指针*/
{ return p->lchild; }
BTNode *RchildNode(BTNode *p) /*返回*p结点的右孩子结点指针*/
{ return p->rchild; }
void CreateBTree(BTNode *&b,char *str)
{
//创建二叉链
int MaxSize1=50;
BTNode *St[MaxSize],*p=NULL;
int top=-1,k,j=0; char ch=str[j];
b=NULL;
while(ch!='\0'){ //str未扫描完时循环
switch(ch){
case '(': top++; St[top]=p; k=1; break; //可能有左孩子结点,进栈
case ')': top--; break;
case ',': k=2; break; //后面为右孩子
default:
p=(BTNode *)malloc(sizeof(BTNode));
p->data=ch;
p->lchild=p->rchild=NULL;
if(b==NULL)
b=p;
else{
switch(k){
case 1: St[top]->lchild=p; break;
case 2: St[top]->rchild=p; break;
}
}
}
j++;
ch=str[j]; //继续扫描str
}
}
void Lchild(BTNode *b,ElemType x)
{
if(b->lchild==NULL && b->rchild == NULL)
cout<<"无左右孩子结点"<<endl;
else if(b->lchild!=NULL && b->rchild !=NULL)
{
if(b->data==x)
{
cout<<"左孩子为:"<<b->lchild->data<<endl;
cout<<"右孩子为:"<<b->rchild->data<<endl;
}
Lchild(b->rchild,x);
Lchild(b->rchild,x);
}
else if(b->lchild=NULL && b->rchild !=NULL)
{
if(b->data==x)
{
cout<<"无左孩子"<<endl;
cout<<"右孩子为:"<<b->rchild->data<<endl;
}
Lchild(b->rchild,x);
Lchild(b->rchild,x);
}
else if(b->lchild !=NULL && b->rchild ==NULL)
{
if(b->data==x)
{
cout<<"左孩子:"<<b->lchild->data<<endl;
cout<<"无右孩子"<<endl;
}
Lchild(b->rchild,x);
Lchild(b->rchild,x);
}
}
int FindNode(BTNode *b,ElemType x)
{
int p;
if (b==NULL)
{return NULL;
}
else if (b->data==x)
{return x;
}
else
{
p=FindNode(b->lchild,x);
if (p!=NULL)
{return p;
}
else
return FindNode(b->rchild,x);
}
}
///队列的有关操作
void InitQueue(SqQueue *&q)
{
q=(SqQueue *)malloc(sizeof(SqQueue));
q->front=q->rear=0;
}
//判断队列是否为空
bool QueueEmpty(SqQueue *q)
{
return (q->front==q->rear);
}
//进队列
bool enQueue(SqQueue *q,BTNode *e)
{
if((q->rear+1)%MaxSize==q->front)//队满溢出
return false;
q->rear=(q->rear+1)%MaxSize;
q->data[q->rear]=e;
return true;
}
//出队列
bool deQueue(SqQueue *&q,BTNode *&e)
{
if(q->front==q->rear)//判断是否队空
return false;
q->front=(q->front+1)%MaxSize;
e=q->data[q->front];
return false;
}
void DestoryBTree(BTNode *&b)
{
if(b!=NULL)
{
DestoryBTree(b->lchild);
DestoryBTree(b->rchild);
free(b);
}
}
void DispBTree(BTNode *b)
{
//输出单链表
if(b!=NULL)
{
cout<<(char)b->data<<" ";
if(b->lchild!=NULL || b->rchild!=NULL)
{
cout<<"(";
DispBTree(b->lchild);
if(b->rchild!=NULL)
cout<<",";
DispBTree(b->rchild);
cout<<")";
}
}
}
int BTHeight(BTNode *b)
{
//树的高度
int lchildh,rchildh;
if(b==NULL)
return(0);
lchildh=BTHeight(b->lchild);
rchildh=BTHeight(b->rchild);
return (lchildh>rchildh)?(lchildh+1):(rchildh+1);
}
void PreOrder(BTNode *b)
{
//先序遍历
if(b!=NULL)
{
cout<<(char)b->data;
PreOrder(b->lchild);
PreOrder(b->rchild);
}
}
void InOrder(BTNode *b)
{
//中序遍历
if(b!=NULL)
{
InOrder(b->lchild);
cout<<(char)b->data;
InOrder(b->rchild);
}
}
void PostOrder(BTNode *b)
{
//后序遍历
if(b!=NULL)
{
PostOrder(b->lchild);
PostOrder(b->rchild);
cout<<(char)b->data;
}
}
void DispLeaf(BTNode *b)
{
//递归输出叶子节点
if(b!=NULL)
{
if(b->lchild==NULL & b->rchild==NULL)
cout<<(char)b->data;
DispLeaf(b->lchild);
DispLeaf(b->rchild);
}
}
int listleaf(BTNode *b)
{
//输出叶子结点个数
int num1;
if(b==NULL)
return 0;
else if(b->lchild==NULL && b->rchild== NULL)
return 1;
num1=listleaf(b->rchild)+listleaf(b->lchild);
return num1;
}
int listnode(BTNode *b)
{
int num;
if(b==NULL)
return(0);
else
{
num=listnode(b->lchild)+listnode(b->rchild)+1;
}
return num;
}
int maxnode(BTNode *b)
{
if(NULL == b)
return 0;
int maxLeft = maxnode(b->lchild);
int maxRight = maxnode(b->rchild);
int max = maxLeft > maxRight ? maxLeft : maxRight;
return max > b->data ? max : b->data;
}
int listfloor(BTNode *b,char x)
{
int num2,m,n;
if(b==NULL)
num2=0;
else if(b->data==x)
num2=1;
else
{
m=listfloor(b->lchild,x);
n= listfloor(b->rchild,x);
if(m==0 && n==0)
num2=0;
else
num2=((m>n)?m:n)+1;
}
return num2;
}
/*
int level(BTNode *b,char n)
{ //假设二叉树结点互不相同
int d1,d2;
if(b==NULL)
return 0;
if((int)b->data==n)
return 1;
d1=level(b->lchild,n);
d2=level(b->rchild,n);
// if(d1*d2)
return 1+(d1>d2?d1:d2);d1*d2????
// return 0;
}
*/
int Level(BTNode *b,ElemType x,int h)
{
int l;
if(b==NULL)
return(0);
else if((char)b->data==(char)x)
return(h);
else
{
l=Level(b->lchild,x,h+1);//左子树中查找
if(l!=0)
return(l);//在左子树中找到,返回l
else
return(Level(b->rchild,x,h+1));//在左子树中未找到再在右子树中查找
}
}
//栈的所有操作如下
void InitStack(SqStack *&s) //初始化栈
{ s=(SqStack *)malloc(sizeof(SqStack));//分配一个是顺序栈空间,首地址存放在s中
s->top=-1; //栈顶指针置为-1
}
void DestroyStack(SqStack *&s) //销毁栈
{
free(s);
}
bool StackEmpty(SqStack *s) //判断栈是否为空
{
return(s->top==-1);
}
bool Push(SqStack *&s,BTNode *e) //进栈
{ if (s->top==MaxSize-1) //栈满的情况,即栈上溢出
return false;
s->top++; //栈顶指针增1
s->data[s->top]=e; //元素e放在栈顶指针处
return true;
}
bool Pop(SqStack *&s,BTNode *&e) //出栈
{ if (s->top==-1) //栈为空的情况,即栈下溢出
return false;
e=s->data[s->top]; //取栈顶指针元素的元素
s->top--; //栈顶指针减1
return true;
}
bool GetTop(SqStack *s,BTNode *&e) //取栈顶元素
{ if (s->top==-1) //栈为空的情况,即栈下溢出
return false;
e=s->data[s->top]; //取栈顶元素
return true;
}
void PreOrder1(BTNode *b) //先序非递归遍历算法1
{
BTNode *p;
SqStack *st; //定义一个顺序栈指针st
InitStack(st); //初始化栈st
Push(st,b); //根节点进栈
while (!StackEmpty(st)) //栈不为空时循环
{
Pop(st,p); //退栈节点p并访问它
printf("%c ",p->data); //访问节点p
if (p->rchild!=NULL) //有右孩子时将其进栈
Push(st,p->rchild);
if (p->lchild!=NULL) //有左孩子时将其进栈
Push(st,p->lchild);
}
printf("\n");
DestroyStack(st); //销毁栈
}
//中序非递归遍历
void InOrder1(BTNode *b) //中序非递归遍历算法
{
BTNode *p;
SqStack *st; //定义一个顺序栈指针st
InitStack(st); //初始化栈st
if (b!=NULL)
{
p=b;
while (!StackEmpty(st) || p!=NULL)
{
while (p!=NULL) //扫描节点p的所有左下节点并进栈
{
Push(st,p); //节点p进栈
p=p->lchild; //移动到左孩子
}
if (!StackEmpty(st)) //若栈不空
{
Pop(st,p); //出栈节点p
printf("%c ",p->data); //访问节点p
p=p->rchild; //转向处理其右子树
}
}
printf("\n");
}
DestroyStack(st); //销毁栈
}
void PostOrder1(BTNode *b) //后序非递归遍历算法
{
BTNode *p,*r;
bool flag;
SqStack *st; //定义一个顺序栈指针st
InitStack(st); //初始化栈st
p=b;
do
{
while (p!=NULL) //扫描节点p的所有左下节点并进栈
{
Push(st,p); //节点p进栈
p=p->lchild; //移动到左孩子
}
r=NULL; //r指向刚刚访问的节点,初始时为空
flag=true; //flag为真表示正在处理栈顶节点
while (!StackEmpty(st) && flag)
{
GetTop(st,p); //取出当前的栈顶节点p
if (p->rchild==r) //若节点p的右孩子为空或者为刚刚访问过的节点
{
printf("%c ",p->data); //访问节点p
Pop(st,p);
r=p; //r指向刚访问过的节点
}
else
{
p=p->rchild; //转向处理其右子树
flag=false; //表示当前不是处理栈顶节点
}
}
} while (!StackEmpty(st)); //栈不空循环
printf("\n");
DestroyStack(st); //销毁栈
}
void LevelOrder(BTNode *b)
{
BTNode *p;
SqQueue *qu;
InitQueue(qu);//初始化队列
enQueue(qu,b);//根结点指针进入队列
while(!QueueEmpty(qu))
//队不为空时循环
{
deQueue(qu,p);//出队结点p
cout<<(char)p->data<<" ";
if(p->lchild!=NULL)//有
{
enQueue(qu,p->lchild);
}
if(p->rchild!=NULL)//有右孩子进队
{
enQueue(qu,p->rchild);
}
}
}
int main()
{
system("cls");
system("color 00a");
BTNode *b;
int i,n;
char x;
cout<<"本程序为二叉树的操作"<<endl;
/*
cout<<"请输入你的字符长度" <<endl;
cin>>n;
cout<<"请输入你的二叉树"<<endl;
char str[n];
for(int k=0;k<n;k++)
{
cin>>str[k];
}
*/
/*
ifstream fileinput;
fileinput.open("E:\\input.txt");
char v[1];
char str[14];
fileinput>>v;
for (int j=1;j<=14;j++)
{
fileinput>>str[j];
}
fileinput.close();
for(int k=1;k<=14;k++)
{
cout<<str[k]<<" ";
}
*/
//char str[20]="A(B(D,E),C(F))";
//int h;
// cout<<"请输入你的二叉树字符的长度"<<endl;
// cin>>h;
char str[20];
cout<<"请输入你的二叉树"<<endl;
cin.getline(str, 20);
CreateBTree(b,str);
cout<<"创建成功" ;
cout<<"是否继续操作继续操作请输入1,否则输入0"<<endl;
cin>>i;
while(i!=0)
{
cout<<"---------------------------------------"<<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;
cout<<"-- 输入【8】后序遍历输出二叉树 ---"<<endl;
cout<<"-- 输入【9】查找x是否在树中(该程序与3重复,跳过) ---"<<endl;
cout<<"-- 输入【10】计算结点个数 ---"<<endl;
cout<<"-- 输入【11】输出该树中结点最大值 ---"<<endl;
cout<<"-- 输入【12】输出树中结点值为x的层 ---"<<endl;
cout<<"-- 输入【13】输出左右孩子结点值 ---"<<endl;
cout<<"-- 输入【14】计算二叉树的各层的宽度---"<<endl;
cout<<"-- 输入【15】计算指定结点所在的层次---"<<endl;
cout<<"-- 输入【16】销毁释放二叉树 ---"<<endl;
cout<<"-- 输入【17】先序非递归算法 ---"<<endl;
cout<<"-- 输入【18】中序非递归算法 ---"<<endl;
cout<<"-- 输入【19】后序非递归算法 ---"<<endl;
cout<<"-- 输入【20】层次遍历(队列)算法 ---"<<endl;
cout<<"-- 请输入你的操作 ---"<<endl;
cout<<"---------------------------------------"<<endl;
cin>>i;
if(i==0)
{
cout<<"程序已经退出"<<endl;
break;
}
else if(i==1)
{
cout<<"二叉树输出为"<<endl;
DispBTree(b);
}
else if(i==2)
{
int h;
h=BTHeight(b);
cout<<"二叉树高度为"<<endl;
cout<<h<<endl;
}
else if(i==3)
{
int y;
ElemType x;
cout<<"请输入你要查找的结点"<<endl;
cin>>x;
y=FindNode(b,x);
if(y==x)
cout<<"该结点存在"<<endl;
else
cout<<"该结点不存在"<<endl;
}
else if(i==4)
{
cout<<"叶子结点显示如下:"<<endl;
DispLeaf(b);
}
else if(i==5)
{
int c;
c=listleaf(b);
cout<<"叶子结点个数为:"<<c<<endl;
}
else if(i==6)
{
cout<<"前序遍历输出为"<<endl;
PreOrder(b);
}
else if(i==7)
{
cout<<"中序遍历输出为"<<endl;
InOrder(b);
}
else if(i==8)
{
cout<<"后序遍历输出为"<<endl;
PostOrder(b);
}
else if(i==9)
{
cout<<"请输入你要查找的字符";
cin>>x;
FindNode(b,x);
}
else if(i==10)
{
int c;
cout<<"查询结点个数";
c=listnode(b);
cout<<"个数为"<<c<<endl;
}
else if(i==11)
{
int d;
d=maxnode(b);
cout<<"最大值为"<<(char)d<<endl;
}
else if(i==12)
{
int e;
char x;
cout<<"请输入你的结点"<<endl;
cin>>x;
e=listfloor(b,x);
cout<<"该数在"<<e<<"层"<<endl;
}
else if(i==13)
{
cout<<"输入你要查找的结点"<<endl;
cin>>x;
Lchild(b,x);
}
else if(i==14)
{
cout<<"二叉树各层高度如下"<<endl;
TreeWidth(b);
}
else if(i==15)
{
int l;
ElemType x;
cout<<"请输入结点(输入对应的ascii码67)"<<endl;
cin>>x;
l=Level(b,x,1);
cout<<"结点所在层次为:"<<l<<endl;
}
else if(i==16)
{
DestoryBTree(b);
cout<<"二叉树释放完成" <<endl;
}
else if(i==17)
{
cout<<"先序非递归算法为:"<<endl;
PreOrder1(b);
}
else if(i==18)
{
cout<<"中序非递归遍历算法为:"<<endl;
InOrder1(b);
}
else if(i==19)
{
cout<<"后序非递归遍历算法为:"<<endl;
PostOrder1(b);
}
else if(i==20)
{
cout<<"基于队列的层次遍历算法为:"<<endl;
LevelOrder(b);
}
}}
/*
实验总结:
方法一:
将数字转化成ascii码只需要在数字前加上(char)
方法二:#include <iostream>
#include "stdio.h";
using namespace std ;
int main()
{
int a=99;
printf("%c",a);
}
*/
/*
字符串长度为:14
程序备用例子: A(B(D,E),C(F))
*/