一、二叉树的链式存储
用链表来表示一颗二叉树,每个结点由三个域组成,除了数据域,还有两个指针域,分别用来存放左右孩子的存储地址。
typedef struct BiTNode
{ char data;
struct BiTNode *lchild, *rchild;
} BiTNode,*BiTree;
二、二叉树的遍历
(一)先序遍历(递归调用)
int PreOrderTraverse(BiTree T){
if(T==NULL) return OK; //空二叉树
else{
cout<<T->data; //访问根结点
PreOrderTraverse(T->lchild); //递归遍历左子树
PreOrderTraverse(T->rchild); //递归遍历右子树
}
}
(二)中序遍历(非递归实现)
非递归中序遍历算法思想
(1)首先二叉树结点指针进栈,然后结点指针指向进栈结点的左子树的跟结点。重复操作(1)直到指针指向空
(2)当栈非空时,从栈中退出一个节点的指针,访问该节点,转为(3)栈为空时,结束算法。
(3)然后将指针指向访问过的节点的右子树的跟
#define MAXNODE 100 //二叉树最大节点数
//定义二叉树链式结构
typedef struct BitNode
{
char data; //数据域
struct BitNode *lchild,*rchild;//左右指针域
}BitNode,*BiTree;
//二叉树进行中序非递归遍历
void NRInorder(BiTree t)
{
BiTree s; //s-指向当前节点
BiTree stack[MAXNODE]; //定义栈
int top=-1; //初始化栈顶指针
if(t==NULL)
return;
stack[++top]=t;//根指针入栈
s=t->lchild; //s指向左子树
while(s!=NULL||top!=-1)//当存在节点(涉及到根下右子树)或者栈不为空,进行遍历
{
while(s!=NULL) //如果存在节点,寻找最左子树并入栈
{
if(top>=MAXNODE-1)
{
printf("栈为满\n");
return;
}
stack[++top]=s;//当前节点入栈
s=s->lchild; //左子树进行遍历
}
if(top==-1)
{
printf("栈为空\n");
return;
}
s=stack[top--]; //弹出栈顶元素到s中
printf("%c ",s->data); //输出当前节点元素值
s=s->rchild; //遍历右子树
}
}
(三)后序遍历
int PostOrderTraverse(BiTtree T)
{
if(T==NULL)
return OK;
else{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data<<" ";
}
}
三、求深度
int Getdepth(BiTtree T)
{
int l,r;
if(!T)
{
return 0;
}
l=Getdepth(T->lchild);
r=Getdepth(T->rchild);
if(l>r)
{
return l+1;
}
else
return r+1;
}
四、求叶子结点个数
void CountLeaf(BiTtree root,int &count)//采用先序遍历的递归算法
{
if ( root!=NULL ) //非空二叉树条件
{
if (!root->lchild && !root->rchild)//是叶子结点则统计并打印
{
count++;
//cout<<root->data<<endl;
}
if(root->lchild)
CountLeaf(root->lchild,count); //递归遍历左子树;
if(root->rchild)
CountLeaf(root->rchild,count); //递归遍历右子树;
}
}
综合代码实现如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define OK 1
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTtree;
int count;
//按先序次序输入二叉树中结点的值,创建二叉树T
void CreatBiTree(BiTtree &T)
{
char ch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=new BiTNode;
T->data=ch;
cout<<"请输入"<<ch<<"的左孩子:";
CreatBiTree(T->lchild);
cout<<"请输入"<<ch<<"的右孩子:";
CreatBiTree(T->rchild);
}
}
//先序遍历
int PreOrderTraverse(BiTtree T)
{
if(T==NULL)
return OK; //空二叉树
else
{
cout<<T->data<<" "; //访问跟结点
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
//中序遍历
/*
int InOrderTraverse(BiTtree T)
{
if(T==NULL)
return OK;
else
{
InOrderTraverse(T->lchild);
cout<<T->data<<" ";
InOrderTraverse(T->rchild);
}
} */
void InOrderTraverse(BiTtree T)
{
if(T!=NULL)
{
BiTNode *stack[100];
int top=-1;
BiTNode *t;
t=T;
while(top!=-1||t!=NULL)
{
while(t!=NULL)
{
stack[++top]=t;
t=t->lchild;
}
if(top!=-1)
{
t=stack[top--];
cout<<t->data<<" ";
t=t->rchild;
}
}
}
}
//后序遍历
int PostOrderTraverse(BiTtree T)
{
if(T==NULL)
return OK;
else{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data<<" ";
}
}
void level(BiTtree T)
{
int front,rear;
front=rear=0;
BiTtree que[100];
BiTtree p;
if(T)
{
rear=(rear+1)%100;
que[rear]=T;
while(front!=rear)
{
front=(front+1)%100;
p=que[front];
cout<<p->data;
if(p->lchild)
{
rear=(rear+1)%100;
que[rear]=p->lchild;
}
if(p->rchild)
{
rear=(rear+1)%100;
que[rear]=p->rchild;
}
}
}
}
int getdepth(BiTtree T)
{
int l,r;
if(!T)
{
return 0;
}
l=getdepth(T->lchild);
r=getdepth(T->rchild);
if(l>r)
{
return l+1;
}
else
return r+1;
}
void CountLeaf(BiTtree root,int &count)//采用先序遍历的递归算法
{
if ( root!=NULL ) //非空二叉树条件
{
if (!root->lchild && !root->rchild)//是叶子结点则统计并打印
{
count++;
//cout<<root->data<<endl;
}
if(root->lchild)
CountLeaf(root->lchild,count); //递归遍历左子树;
if(root->rchild)
CountLeaf(root->rchild,count); //递归遍历右子树;
}
}
void show_help()
{
cout<<"|------------------------------------------"<<endl;
cout<<"| 0.创建二叉树 "<<endl;
cout<<"| 1.先序遍历二叉树 "<<endl;
cout<<"| 2.中序遍历二叉树 "<<endl;
cout<<"| 3.后序遍历二叉树 "<<endl;
cout<<"| 4.二叉树的层序遍历 "<<endl;
cout<<"| 5.二叉树的深度 "<<endl;
cout<<"| 6.二叉树的叶子结点数 "<<endl;
cout<<"|------------------------------------------"<<endl;
}
int main()
{
BiTtree root;
int operate_code;
show_help();
cout<<"请建立二叉树并输入二叉树的根结点"<<endl;
CreatBiTree(root);
while(1)
{
cout<<"请选择功能 "<<endl;
cin>>operate_code;
count=0;
if(operate_code==1)
{
if(root)
{
cout<<"先序输出的结果为:";
PreOrderTraverse(root);
cout<<endl;
}
else
cout<<"该二叉树为空"<<endl;
}
else if(operate_code==2)
{
if(root)
{
cout<<"中序输出的结果为:";
InOrderTraverse(root);
cout<<endl;
}
else
cout<<"该二叉树为空"<<endl;
}
else if(operate_code==3)
{
if(root)
{
cout<<"后序输出的结果为:";
PostOrderTraverse(root);
cout<<endl;
}
else
cout<<"该二叉树为空"<<endl;
}
else if(operate_code==4)
{
cout<<"二叉树的层序遍历是";
level(root);
cout<<endl;
}
else if(operate_code==5)
{
cout<<"二叉树的深度是"<<getdepth(root)<<endl;
}
else if(operate_code==6)
{
CountLeaf(root,count);
cout<<"二叉树的叶子节点个数为"<<count<<endl;
}
}
}