创建一棵二叉树,分别实现先序、中序和后序遍历一棵二叉树,计算二叉树结点个数等操作等。
头文件:BTree.h
#include<iostream.h>
#include<math.h>
int couter=0;//全局变量,用于存储二叉树的叶子总数
//二叉树链结点类:
class BTreeNode
{
friend class BTree;
friend class Queue;
int data;
BTreeNode *lchild,*rchild;
public:
BTreeNode():lchild(NULL),rchild(NULL){};
BTreeNode(int d,BTreeNode *l=NULL,BTreeNode *r=NULL):data(d),lchild(l),rchild(r){};
int getdata(){return data;};
BTreeNode *getleft(){return lchild;};
BTreeNode *getright(){return rchild;};
};
//队列类(为层次遍历而定义的):
class Queue
{
protected:
friend class BTree;
int front,rear,count;
BTreeNode *elem[100];
int maxsz;//队列
public:
Queue(int n){maxsz=n;front=rear=count=0;};//队列构造函数
bool Enqueue(BTreeNode *p); //结点入列
BTreeNode *Dequeue(); //结点出列
bool IsEmpty(){return count==0;}; //判断队列是否为空
};
bool Queue::Enqueue(BTreeNode *p)
{
if(!(count>=100))
{
elem[rear]=p;
rear=(rear+1)%maxsz;
count++;
return true;
}
else return false;
}
BTreeNode *Queue::Dequeue()
{
BTreeNode *el;
if(!IsEmpty())
{
el=elem[front];
front=(front+1)%maxsz;
count--;
return el;
}
else return NULL;
}
//单链表结点类:
class Node
{
friend class List;
int Ndata;
Node *next;
public:
Node(int d=0,Node *n=NULL):Ndata(d),next(n){};
void setnext(Node *p){next=p;};
};
//单链表类:
class List
{
private:
friend class BTree;
Node *head,*tail;
int size;
public:
List(){head=new Node();size=0;};//构造函数
List(int a[],int n)//构造函数,建链表
{
Node *p;head=new Node(0,NULL);
for(int i=n-1;i>=0;i--)
{
p=new Node(a[i],head->next);
head->setnext(p);
}
size=n;};
~List(){delete []head;};//析构函数
int get(int i)//取元素值
{
Node *p=head;int j=0;
while(p!=NULL&&j<i)
{
p=p->next;j=j+1;
}
if(p!=NULL&&j==i)return p->Ndata;
else return NULL;
};
void print()//打印各元素值
{
cout<<"\n 单链表的各叶子结点值为:\n\t";
for(int i=1;i<=size;i++)
cout<<get(i)<<" ";
};
};
//二叉树类:
class BTree
{
int *a;int n;
BTreeNode *build0(int i);//递归创建二叉链表
protected:
BTreeNode *root; //二叉树的根结点
public:
BTree(BTreeNode *p=NULL){copybt(root,p);};
BTree(int a[],int n){this->a=a;this->n=n;root=build0(1);};
void build(int a[],int n){this->a=a;this->n=n;root=build0(1);}; //相当于构造函数,用于二叉树初始化
int num(){return num(root);}; //求结点个数
static int num(BTreeNode *p){if(p==NULL)return 0;else return num(p->lchild)+num(p->rchild)+1;};
int dep(){return dep(root);}; //求二叉树的高度(深度)
static int dep(BTreeNode *p);
bool equal(BTree& bt){if(equal(root,bt.root)==true)return 1;else return 0;};//判断两棵二叉树是否相等
static bool equal(BTreeNode *p,BTreeNode *q);
void dest(BTreeNode *p); //释放存储空间
void copybt(BTree &bt){dest(root);copybt(root,bt.root);}; //复制一棵二叉树
static void copybt(BTreeNode *&p,BTreeNode *q);
void preorder(void visit(BTreeNode *p)){preorder(root,visit);cout<<endl;}; //前序遍历(递归)
static void preorder(BTreeNode *p,void visit(BTreeNode *p));
void preorder1(void visit(BTreeNode *p)); //前序遍历(非递归)
void inorder(void visit(BTreeNode *p)){inorder(root,visit);cout<<endl;}; //中序遍历(递归)
static void inorder(BTreeNode *p,void visit(BTreeNode *p));
void inorder1(void visit(BTreeNode *p)); //中序遍历(非递归)
void postorder(void visit(BTreeNode *p)){postorder(root,visit);cout<<endl;};//后序遍历(递归)
static void postorder(BTreeNode *p,void visit(BTreeNode *p));
void postorder1(void visit(BTreeNode *p)); //后序遍历(非递归)
void layerorder(); //层次遍历
void exchange(BTreeNode *t); //交换左右子树
void exchange(){BTree::exchange(root);};
void BTreeL();
void print(){print(root,1);};//输出二叉树
void print(BTreeNode *p,int l);
void leaves(BTreeNode *t); //求叶子总数
void leaves(){BTree::leaves(root);};
};
BTreeNode *BTree::build0(int i)
{
BTreeNode *p;int l,r;
if((i<=n)&&(a[i-1]!=' '))
{
p=new BTreeNode;p->data=a[i-1];
l=2*i;r=2*i+1;
p->lchild=build0(l);
p->rchild=build0(r);
return p;
}
else return NULL;
};
int BTree::dep(BTreeNode *p)
{
int max;
if(p==NULL)return 0;
else
{
max=dep(p->lchild);
if(dep(p->rchild)>max)max=dep(p->rchild);
return max+1;//加上根结点
}
};
bool BTree::equal(BTreeNode *p,BTreeNode *q)
{
bool b;
if(p==NULL&&q==NULL)b=true;
else if(p==NULL||q==NULL)b=false;
else b=(p->data==q->data)&&equal(p->lchild,q->lchild)&&equal(p->rchild,q->rchild);
return b;
};
void BTree::dest(BTreeNode *p)
{
if(p!=NULL)
{
dest(p->lchild);
dest(p->rchild);
delete p;
}
};
void BTree::copybt(BTreeNode *&p,BTreeNode *q)
{
if(q==NULL)p=NULL;//复制一棵空树
else
{
p=new BTreeNode;
p->data=q->data;
copybt(p->lchild,q->lchild);
copybt(p->rchild,q->rchild);
}
};
void BTree::preorder(BTreeNode *p,void visit(BTreeNode *p))
{
if(p!=NULL)
{
visit(p);//访问结点,并输出结点数据
preorder(p->lchild,visit);
preorder(p->rchild,visit);
}
};
void BTree::preorder1(void visit(BTreeNode *p))
{
BTreeNode *stack[100],*p;
int top=0;
stack[top]=root;
while(top>=0)
{
while(stack[top]!=NULL)
{
visit(stack[top]);
p=stack[top]->lchild;
stack[++top]=p;
}
top--;
if(top>=0)
{
p=stack[top];
stack[top]=p->rchild;
}
}
cout<<endl;
};
void BTree::inorder(BTreeNode *p,void visit(BTreeNode *p))
{
if(p!=NULL)
{
inorder(p->lchild,visit);
visit(p);
inorder(p->rchild,visit);
}
};
void BTree::inorder1(void visit(BTreeNode *p))
{
BTreeNode *stack[100],*p;
int top=0;
stack[top]=root;
while(top>=0)
{
while(stack[top]!=NULL)
{
p=stack[top]->lchild;
stack[++top]=p;
}
top--;
if(top>=0)
{
p=stack[top];
visit(p);
stack[top]=p->rchild;
}
}
cout<<endl;
};
void BTree::postorder(BTreeNode *p,void visit(BTreeNode *p))
{
if(p!=NULL)
{
postorder(p->lchild,visit);
postorder(p->rchild,visit);
visit(p);
}
};
void BTree::postorder1(void visit(BTreeNode *p))
{
///*
//第一种方式:
struct stacknode//用结构类型定义栈元素类型
{
BTreeNode *d;
int flag; //定义标志变量
};
BTreeNode *p=root;
stacknode *stack;
stack=new stacknode[num()];
int top=0;
while(p!=NULL||top!=0)
{
if(p!=NULL)
{
stack[++top].d=p; //结点进栈
stack[top].flag=1; //奇次访问,标志值为1
p=p->lchild;
}
else if(stack[top].flag)//判断栈顶的标志是否为1,若是,则标志出栈
{
stack[top].flag=0; //偶次访问,标志值为0
p=stack[top].d->rchild;
}
else
{
visit(stack[top--].d);//p=stack[top].d;cout<<" "<<p->data;top--;
p=NULL;
}
}
delete []stack;//释放空间
cout<<endl;
//*/
//第二种方式:
/*
BTreeNode *stack[100];//定义栈,存储结点
int top=0,flag[100];//定义标志数组flag
stack[top]=root;
flag[top]=0;
do
{
while(stack[top]!=NULL)
{
stack[++top]=stack[top]->lchild;
flag[top]=0;//第一次访问,标志置为0
}
while(flag[top-1]==1)visit(stack[--top]);//cout<<" "<<stack[--top]->data;
if(top>0) //栈不为空
{
stack[top]=stack[top-1]->rchild;
flag[top]=0; //栈顶标志值为0(也可当做是第一次访问)
flag[top-1]=1;//第二次访问,标志置为1
}
}while(top!=0);
cout<<endl;
/*/
};
void BTree::layerorder()
{
Queue q(num());
BTreeNode *t=root;
if(t!=NULL)q.Enqueue(t); //结点入列
cout<<"\t";
while(!q.IsEmpty())
{
t=q.Dequeue(); //结点出列
cout<<t->data<<" ";//输出该结点的数据
if(t->lchild!=NULL)q.Enqueue(t->lchild);//若左孩子非空,则左孩子入列
if(t->rchild!=NULL)q.Enqueue(t->rchild);//若右孩子非空,则右孩子入列
}
}
void BTree::exchange(BTreeNode *t)
{
BTreeNode *x;
if(t!=NULL)
{
x=t->lchild;t->lchild=t->rchild;t->rchild=x;//交换左右子树的结点
exchange(t->lchild);
exchange(t->rchild);
}
};
void BTree::BTreeL()
{
BTreeNode *stack[100],*p;
int top=0,i=0;
stack[top]=root;
while(top>=0)
{
while(stack[top]!=NULL)
{
p=stack[top]->lchild;
stack[++top]=p;
}
top--;
if(top>=0)
{
p=stack[top];
if(p->lchild==NULL&&p->rchild==NULL)a[i++]=p->data;
stack[top]=p->rchild;
}
}
List L(a,i);
L.print();
cout<<endl;
};
void BTree::print(BTreeNode *p,int l)
{
if(p!=NULL)
{
print(p->rchild,l+1);
for(int i=0;i<6*(l-1);i++)cout<<" ";
cout<<"..."<<p->data<<endl;
print(p->lchild,l+1);
}
else if(num()==0)
cout<<"\t\t空树!\n";
};
void BTree::leaves(BTreeNode *t)
{
if(t!=NULL)
{
if(t->lchild==NULL&&t->rchild==NULL)couter++;
leaves(t->lchild);
leaves(t->rchild);
}
};
void f(BTreeNode *p)//visit()函数输出
{
cout<<" "<<p->getdata();
};
void func(int a[],int n)
{
cout<<"输入二叉树的各个元素值:\n";
for(int i=0;i<n;i++)
cin>>a[i];
};
main函数:
#include "BTree.h"
void main()
{
int a[]={0,1,2,3,4,5,6,7,8,9};
BTree bt(a,10);//程序自动初始化
BTree bt1; //定义一个新对象,用于建立一棵新的二叉树,进行复制、比较等
int chioce,finial=1;
cout<<"\n****************** 菜单 *************************\n";
cout<<"\n\t 1--建立一棵二叉树\n\t 2--前序遍历递归算法\n\t 3--前序遍历非递归算法\n\t 4--中序遍历递归算法\n\t 5--中序遍历非递归算法\n"
<<"\t 6--后序遍历递归算法\n\t 7--后序遍历非递归算法\n\t 8--层次遍历算法\n\t 9--求树高\n\t10--求叶子总数\n"
<<"\t11--交换左右子树\n\t12--复制一棵二叉树\n\t13--判断两棵二叉树是否相等\n\t14--输出二叉树\n\t15--二叉树叶子结点→单链表<左→右>\n\t16--退出\n";
while(finial!=0)
{
cout<<"\n请选择<1~16>:";
cin>>chioce;
while(chioce>16||chioce<1){cout<<"\n对不起,您的选择不正确!请重新选择<1~15>:";cin>>chioce;}
switch(chioce)
{
case 1:
int b[100],n;
cout<<"\n输入二叉树的元素个数(<=100):";cin>>n;
func(b,n);//调用函数进行初始化
bt.build(b,n);break;
case 2:cout<<"\n前序遍历(递归):\n";bt.preorder(f);break;
case 3:cout<<"\n前序遍历(非递归):\n";bt.preorder1(f);break;
case 4:cout<<"\n中序遍历(递归):\n";bt.inorder(f);break;
case 5:cout<<"\n中序遍历(非递归):\n";bt.inorder1(f);break;
case 6:cout<<"\n后序遍历(递归):\n";bt.postorder(f);break;
case 7:cout<<"\n后序遍历(非递归):\n";bt.postorder1(f);break;
case 8:cout<<"\n层次遍历:\n";bt.layerorder();break;
case 9:cout<<"\n\t该二叉树的树高为:"<<bt.dep()<<endl;break;
case 10:
bt.leaves();
cout<<"\n\t该二叉树的叶子总数为:"<<couter<<endl;
couter=0;break;//初始化
case 11:bt.exchange();cout<<"\n\t已成功交换该二叉树的左右子树!\n";break;
case 12:
bt1.copybt(bt);
cout<<"\n\t已复制成功!\n 该二叉树是:\n";
bt1.print();break;
case 13:
cout<<"\n 因为这两棵二叉树分别是:\n\n\t第一棵:\n";bt.print();
cout<<"\n\t第二棵:\n";bt1.print();
if(bt.equal(bt1)==1)
cout<<"\n 所以:\n\t这两棵二叉树是相等的!\n";
else
cout<<"\n 所以:\n\t这两棵二叉树是不相等的!\n";break;
case 14:cout<<"\n该二叉树是:\n";bt.print();break;
case 15:bt.BTreeL();break;
case 16:finial=0;cout<<"\n\t退出程序!谢谢您的使用!\n\n";break;
}
}
}
截图: