递归创建二叉树
利用括号嵌套的字符串建立二叉链表(递归,与非递归)
先序遍历二叉树的递归实现
中序遍历二叉树的递归实现
后序遍历二叉树的递归实现
先序遍历二叉树的非递归实现
中序遍历二叉树的非递归实现
后序遍历二叉树的非递归实现
二叉树的层次遍历
销毁二叉树操作
二叉树的左插入操作
二叉树的右插入操作
查找元素值为e的结点的指针
返回二叉树的左右孩子结点元素值操作
二叉树的左(右)删除操作
计算二叉树的深度,叶子节点个数
#include <iostream>
#include <string.h>
#include <stdio.h>
typedef char DataType;
#define MaxSize 100
using namespace std;
typedef struct Node //二叉链表存储结构类型定义
{
DataType data; //数据域
struct Node *lchild; //指向左孩子结点
struct Node *rchild; //指向右孩子结点
}*BiTree,BitNode;
void InitBitTree(BiTree *T)
//二叉树的初始化操作
{
*T=NULL;
}
void DestroyBitTree(BiTree *T)
//销毁二叉树操作
{
if(*T) //如果是非空二叉树
{
if((*T)->lchild)
DestroyBitTree(&((*T)->lchild));
if((*T)->rchild)
DestroyBitTree(&((*T)->rchild));
free(*T);
*T=NULL;
}
}
void CreateBitTree(BiTree *T)
//递归创建二叉树
{
DataType ch;
scanf("%c",&ch);
if(ch=='#')
*T=NULL;
else
{
*T=(BiTree)malloc(sizeof(BitNode)); //生成根结点
if(!(*T))
{
exit(-1);
}
(*T)->data=ch;
CreateBitTree(&((*T)->lchild)); //构造左子树
CreateBitTree(&((*T)->rchild)); //构造右子树
}
}
int InsertLeftChild(BiTree p,BiTree c)
//二叉树的左插入操作
{
if(p) //如果指针p不空
{
c->rchild=p->lchild; //p的原来的左子树成为c的右子树
p->lchild=c; //子树c作为p的左子树
return 1;
}
return 0;
}
int InsertRightChild(BiTree p,BiTree c)
//二叉树的右插入操作
{
if(p) //如果指针p不空
{
c->rchild=p->rchild; //p的原来的右子树作为c的右子树
p->rchild=c; //子树c作为p的右子树
return 1;
}
return 0;
}
BiTree Point(BiTree T,DataType e)
//查找元素值为e的结点的指针
{
BiTree Q[MaxSize]; //定义一个队列,用于存放二叉树中结点的指针
int front=0,rear=0; //初始化队列
BitNode *p;
if(T) //如果二叉树非空
{
Q[rear]=T;
rear++;
while(front!=rear) //如果队列非空
{
p=Q[front]; //取出队头指针
front++; //将队头指针出队
if(p->data==e)
return p;
if(p->lchild) //如果左孩子结点存在,将左孩子指针入队
{
Q[rear]=p->lchild; //左孩子结点的指针入队
rear++;
}
if(p->rchild) //如果右孩子结点存在,将右孩子指针入队
{
Q[rear]=p->rchild; //右孩子结点的指针入队
rear++;
}
}
}
return NULL;
}
DataType LeftChild(BiTree T,DataType e)
//返回二叉树的左孩子结点元素值操作
{
BiTree p;
if(T) //如果二叉树不空
{
p=Point(T,e); //p是元素值e的结点的指针
if(p&&p->lchild) //如果p不为空且p的左孩子结点存在
return p->lchild->data; //返回p的左孩子结点的元素值
}
return 0;
}
DataType RightChild(BiTree T,DataType e)
//返回二叉树的右孩子结点元素值操作
{
BiTree p;
if(T) //如果二叉树不空
{
p=Point(T,e); //p是元素值e的结点的指针
if(p&&p->rchild) //如果p不为空且p的右孩子结点存在
return p->rchild->data; //返回p的右孩子结点的元素值
}
return 0;
}
int DeleteLeftChild(BiTree p)
//二叉树的左删除操作
{
if(p) //如果p不空
{
DestroyBitTree(&(p->lchild)); //删除左子树
return 1;
}
return 0;
}
int DeleteRightChild(BiTree p)
//二叉树的左删除操作
{
if(p) //如果p不空
{
DestroyBitTree(&(p->rchild)); //删除右子树
return 1;
}
return 0;
}
void Queue(BiTree T)
{
BiTree queue[100];
BiTree p;
int front=0,rear=0;
if(T==NULL)
{
return;
}
queue[rear++]=T;
while (front!=rear)
{
p=queue[front++];
printf("%c ",p->data);
if(p->lchild)
{
queue[rear++]=p->lchild;
}
if(p->rchild)
{
queue[rear++]=p->rchild;
}
}
}
//函数的声明
void PreOrderTraverse(BiTree T); //二叉树的先序遍历的递归函数声明
void InOrderTraverse(BiTree T); //二叉树的中序遍历的递归函数声明
void PostOrderTraverse(BiTree T); //二叉树的后序遍历的递归函数声明
void PreOrderTraverse2(BiTree T); //二叉树的先序遍历的非递归函数声明
void InOrderTraverse2(BiTree T); //二叉树的中序遍历的非递归函数声明
void PostOrderTraverse2(BiTree T); //二叉树的后序遍历的非递归函数声明
void CreateBitTree2(BiTree *T,char str[]); //利用括号嵌套的字符串建立二叉树的函数声明
void QueueTraverse(BiTree T); //二叉树的层次序遍历函数声明
int GetHeight(BiTree T); //二叉树深度函数声明
int CountLeaf(BiTree T); //二叉树叶子结点个数函数声明
int NotLeafCount(BiTree T); //统计二叉树中非叶子结点数目
int main()
{
char str[]="A(B(D(,H(J,)),E(,I)),C(F,G))";
BiTree T,root;
InitBitTree(&T);
printf("根据输入二叉树的先序序列创建二叉树('#'表示结束):\n");
CreateBitTree(&T);
printf("二叉树的先序序列:\n");
printf("递归:\t");
PreOrderTraverse(T);
printf("\n");
printf("非递归:");
PreOrderTraverse2(T);
printf("\n");
printf("二叉树的中序序列:\n");
printf("递归:\t");
InOrderTraverse(T);
printf("\n");
printf("非递归:");
InOrderTraverse2(T);
printf("\n");
printf("二叉树的后序序列:\n");
printf("递归:\t");
PostOrderTraverse(T);
printf("\n");
printf("非递归:");
PostOrderTraverse2(T);
printf("\n");
printf("根据括号嵌套的字符串建立二叉树:\n");
CreateBitTree2(&root,str);
printf("二叉树的先序序列:\n");
PreOrderTraverse(root);
printf("\n");
printf("二叉树的中序序列:\n");
InOrderTraverse(root);
printf("\n");
printf("二叉树的后序序列:\n");
PostOrderTraverse(root);
printf("\n");
printf("二叉树的层次遍历序列:\n");
QueueTraverse(root);
printf("\n");
printf("二叉树的深度:\n");
printf("%2d\n",GetHeight(root));
printf("二叉树叶子结点个数:\n");
printf("%2d\n",CountLeaf(root));
printf("非叶子结点个数:\n%2d\n",NotLeafCount(root));
DestroyBitTree(&T);
DestroyBitTree(&root);
return 0;
}
void CreateBitTree2(BiTree *T,char str[])
//利用括号嵌套的字符串建立二叉链表
{
char ch;
BiTree stack[MaxSize]; //定义栈,用于存放指向二叉树中结点的指针
int top=-1; //初始化栈顶指针
int flag=-1,k;
BitNode *p=NULL;
*T=NULL,k=0;
ch=str[k];
while(ch!='\0') //如果字符串没有结束
{
switch(ch)
{
case '(':
stack[++top]=p;
flag=1;
break;
case ')':
top--;
break;
case ',':
flag=2;
break;
default:
p=(BiTree)malloc(sizeof(BitNode));
p->data=ch;
p->lchild=NULL;
p->rchild=NULL;
if(*T==NULL) //如果是第一个结点,表示是根结点
*T=p;
else
{
switch(flag)
{
case 1:
stack[top]->lchild=p;
break;
case 2:
stack[top]->rchild=p;
break;
}
}
}
ch=str[++k];
}
}
void PreOrderTraverse(BiTree T)
//先序遍历二叉树的递归实现
{
if(T) //如果二叉树不为空
{
printf("%2c",T->data); //访问根结点
PreOrderTraverse(T->lchild); //先序遍历左子树
PreOrderTraverse(T->rchild); //先序遍历右子树
}
}
void InOrderTraverse(BiTree T)
//中序遍历二叉树的递归实现
{
if(T) //如果二叉树不为空
{
InOrderTraverse(T->lchild); //中序遍历左子树
printf("%2c",T->data); //访问根结点
InOrderTraverse(T->rchild); //中序遍历右子树
}
}
void PostOrderTraverse(BiTree T)
//后序遍历二叉树的递归实现
{
if(T) //如果二叉树不为空
{
PostOrderTraverse(T->lchild); //后序遍历左子树
PostOrderTraverse(T->rchild); //后序遍历右子树
printf("%2c",T->data); //访问根结点
}
}
void PreOrderTraverse2(BiTree T)
//先序遍历二叉树的非递归实现
{
BiTree stack[MaxSize]; //定义一个栈,用于存放结点的指针
int top; //定义栈顶指针
BitNode *p; //定义一个结点的指针
top=0; //初始化栈
p=T;
while(p!=NULL||top>0)
{
while(p!=NULL) //如果p不空,访问根结点,遍历左子树
{
printf("%2c",p->data); //访问根结点
stack[top++]=p; //将p入栈
p=p->lchild; //遍历左子树
}
if(top>0) //如果栈不空
{
p=stack[--top]; //栈顶元素出栈
p=p->rchild; //遍历右子树
}
}
}
void InOrderTraverse2(BiTree T)
//中序遍历二叉树的非递归实现
{
BiTree stack[MaxSize]; //定义一个栈,用于存放结点的指针
int top; //定义栈顶指针
BitNode *p; //定义一个结点的指针
top=0; //初始化栈
p=T;
while(p!=NULL||top>0)
{
while(p!=NULL) //如果p不空,访问根结点,遍历左子树
{
stack[top++]=p; //将p入栈
p=p->lchild; //遍历左子树
}
if(top>0) //如果栈不空
{
p=stack[--top]; //栈顶元素出栈
printf("%2c",p->data); //访问根结点
p=p->rchild; //遍历右子树
}
}
}
void PostOrderTraverse2(BiTree T)
//后序遍历二叉树的非递归实现
{
BiTree stack[MaxSize]; //定义一个栈,用于存放结点的指针
int top; //定义栈顶指针
BitNode *p,*q; //定义结点的指针
top=0; //初始化栈
p=T,q=NULL; //初始化结点的指针
while(p!=NULL||top>0)
{
while(p!=NULL) //如果p不空,访问根结点,遍历左子树
{
stack[top++]=p; //将p入栈
p=p->lchild; //遍历左子树
}
if(top>0) //如果栈不空
{
p=stack[top-1]; //取栈顶元素
if(p->rchild==NULL||p->rchild==q) //如果p没有右孩子结点,或右孩子结点已经访问过
{
printf("%2c",p->data); //访问根结点
q=p;
p=NULL;
top--;
}
else
p=p->rchild;
}
}
}
void QueueTraverse(BiTree T)
{
BiTree queue[MaxSize]; //定义一个队列,用于存放结点的指针
int front=-1,rear=-1; //定义队列头,尾指针
BiTree p;
if(T==NULL)
{
return;
}
rear=(rear+1)%MaxSize;
queue[rear]=T; //如果根结点不为空,则根结点先入队列
while (front!=rear)
{
front=(front+1)%MaxSize;
p=queue[front]; //如果队列不为空,则出队一个节点
printf("%2c",p->data);
if(p->lchild)
{
rear=(rear+1)%MaxSize;
queue[rear]=p->lchild; //当前结点的左孩子不为空则入队
}
if(p->rchild)
{
rear=(rear+1)%MaxSize;
queue[rear]=p->rchild; //当前结点的右孩子不为空则入队
}
}
}
int GetHeight(BiTree T)
{
int lh,rh;
if(T==NULL)
{
return 0; //空树,深度0
}
lh=GetHeight(T->lchild); //递归调用获得左子树的深度
rh=GetHeight(T->rchild); //递归调用获得右子树的深度
if(lh>=rh) //取左右字树深度最大者,作为字树的深度,这个树的深度是字树深度加1
{
return lh+1;
}
return rh+1;
}
int CountLeaf(BiTree T)
{
int lnum,rnum;
if(T==NULL)
{
return 0;
}
lnum=CountLeaf(T->lchild); //递归求左子树叶子结点个数
rnum=CountLeaf(T->rchild); //递归求右子树叶子结点个数
if(lnum+rnum==0)
{
return 1; //如果左右字树叶子的和为0,说明是叶子结点返回1,否则返回左右子树叶子结点的和
}
else
{
return lnum+rnum;
}
}
int NotLeafCount(BiTree T)
{
if(T==NULL)
{
return 0;
}
if(!T->rchild && !T->lchild) //如果是叶子结点,返回0
{
return 0;
}
return NotLeafCount(T->lchild)+NotLeafCount(T->rchild)+1; //左右子树的非叶子结点数目加上根结点的个数
}
根据括号方式递归创建二叉树:
#include <iostream>
using namespace std;
struct BTree
{
char ch;
BTree *lchild,*rchild;
BTree()
{
lchild=rchild=NULL;
}
};
void PreOrder(BTree *root)
{
if(root==NULL)
{
return;
}
printf("%c ",root->ch);
PreOrder(root->lchild);
PreOrder(root->rchild);
}
void PostOrder(BTree *root)
{
if(root==NULL)
{
return;
}
PostOrder(root->lchild);
PostOrder(root->rchild);
printf("%c ",root->ch);
}
int cnt;
void CreatBinaryTree(BTree *&root,char *str)
{
if(str[cnt]>='a' && str[cnt]<='z')//创建结点
{
root=new BTree;
root->ch=str[cnt++];
}
if(str[cnt]=='(') //准备创建左右孩子
{
cnt++;
CreatBinaryTree(root->lchild, str);
CreatBinaryTree(root->rchild, str);
}
if(str[cnt]==',') //右子树创建完毕,返回
{
cnt++;
return;
}
if(str[cnt]==')') //左右子树创建完毕,返回
{
cnt++;
return;
}
}
int main()
{
BTree *root;
cnt=0;
char str[]="a(b(c,d),e(f,g))";
char str2[]="a(b(d,e(h,)),c(f(,i),g(j,k)))";
CreatBinaryTree(root, str2);
PreOrder(root);
printf("\n");
PostOrder(root);
}