#include<stdio.h>
#include<stdlib.h>
#define DataType char
typedef struct node{
DataType data;
struct node *lchild,*rchild;
}BinTNode;
typedef BinTNode * BinTree ;
/*************************************
* 函数作用:创建树结构(非递归)
* 函数名:CreateTree
* 参数列表:char *str
* 输入示例:a(b(c(d,e),f),g)
* 返回类型:BinTNode
*************************************/
BinTNode * CreateTree(char *str)
{
BinTNode *St[100];//创建一个指针数组,这个数组是一个用来确定创建的子树的父亲是谁
BinTNode *p=NULL;//创建一个指针等于空
int top,k,j=0;//top是栈顶指针,k是创建左右孩子的标志位,j是取字符数组的索引
top = -1;//置空栈
char ch = str[j];//获取str中的一个字符
BinTNode *b = NULL;//创建头指针
while(ch!='\0')//如果不是字符串结束符
{
switch (ch)//根据字符进行判断
{
case '(':++top;St[top]=p;k=1;break;//如果是左括号,说明开始了一个新的非空子树,将上一轮子树压入堆栈,
case ')':--top;break;//如果是右括号说明一个子树结束,栈指针回到
case ',':k = 2;break;//如果是逗号说明要创建这棵子树的右孩子了
default:
p=(BinTNode *)malloc(sizeof(BinTNode));/*如果符号是一个元素则开辟空间*/
p->data=ch;//并把新开辟的空间中的data赋值为这个元素
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;//将此树的父亲的右孩子指针指向这棵树
}
}
break;//退出switch
}
j++;//j++为取下一个字符做准备
ch = str[j];//取下一个字符
}
return b;
}
/*************************************
* 函数作用:创建树结构(非递归)
* 函数名:CreateBinTree
* 参数列表:BinTree bt
* 输入示例:abcdefjh@#
* 返回类型:BinTree
*************************************/
BinTree CreateBinTree(BinTree bt)
{
BinTNode *Q[100];//定义一个队列,用来保存树的关系
BinTNode *s;//用来为下面开辟空间而准备的野指针
int front,rear;//定义队列的头尾指针
char ch;//用来保存字符数据的中间变量
ch = getchar();//获取第一个字符
bt = NULL;//将二叉树置空
front = 0;//将对头指针置为0
rear = 0;//将队尾指针置为0,队尾和队首指针指在一起表示队列是空的
while(ch!='#')//如果不是结束符
{
if (ch!='@')//如果不是空节点
{
s = (BinTNode *)malloc(sizeof(BinTNode));//申请一个树节点的空间
s->data=ch;//把树的数据域赋值为ch
s->lchild = s->rchild = NULL;//将树的左右子树置空
Q[rear]=s;//将在这个节点压入队列
++rear;//队尾指针自增
if(rear==1)//如果rear是1代表这个节点是跟节点
{
bt = s;//把这个节点连接在头节点上
}
else//如果这个节点不是头节点
{
if(s!=NULL && Q[front]!=NULL)//并且这个节点 s!=NULL有用么 头指针不为空有什么用
{
if(rear % 2 == 0)//如果这个节点可以整除2说明这个节点必然是左子树(树的左儿子在序列中是2n(n代表这个树的序号))
{
Q[front]->lchild=s;//将头指针的左儿子指向这棵树
}
else//否则说明这个节点应该是右子树
{
Q[front]->rchild=s;//将右儿子指向这个节点
}
}
if(rear %2 != 0)//如果已经输入完一颗子树也就是输入完了这棵子树的左右两个孩子
{
++front;//换下一棵空着的树
}
}
}
ch = getchar();//获取下一个字符
}
return bt;//循环结束返回头节点
}
/*************************************
* 函数作用:树的前序遍历
* 函数名:Preorder
* 参数列表:BinTree bt
* 返回类型:void
*************************************/
void Preorder(BinTree bt)
{
if(bt!=NULL)
{
printf("%c",bt->data);
if(bt->lchild || bt->rchild)//这个节点不是子叶节点
{
printf("(");
Preorder(bt->lchild);
printf(",");
Preorder(bt->rchild);
printf(")");
}
}
}
/*************************************
* 函数作用:树的中序遍历
* 函数名:Inorder
* 参数列表:BinTree bt
* 返回类型:void
*************************************/
void Inorder(BinTree bt)
{
if(bt!=NULL)
{
Inorder(bt->lchild);
printf("%c",bt->data);
Inorder(bt->rchild);
}
}
/*************************************
* 函数作用:树的后序遍历
* 函数名:Postorder
* 参数列表:BinTree bt
* 返回类型:void
*************************************/
void Postorder(BinTree bt)
{
if(bt!=NULL)
{
Postorder(bt->lchild);
Postorder(bt->rchild);
printf("%c",bt->data);
}
}
/*************************************
* 函数作用:树的中序遍历(非递归)
* 函数名:Inorder1
* 参数列表:BinTree bt
* 返回类型:void
*************************************/
void Inorder1(BinTree bt)
{
BinTNode *ST[100];//用指针数组来模拟栈
int top = 0;//初始化栈顶指针
ST[top]=bt;//把头节点压入堆栈
do{
while(ST[top]!=NULL)//把跟节点和所有左子树都压入堆栈
{
++top;//栈顶指针加一
ST[top] = ST[top-1]->lchild;//将上一个节点的左子树压入堆栈
}
--top;//全部压入后top指向了一个空节点,所以回退到上一个右元素的节点
if(top>=0)//回退后如果不是-1也就是说树不是一个元素没有
{
printf("%c",ST[top]->data);//访问这个节点,因为这个节点已经没有左子树了
ST[top] = ST[top]->rchild;//将这个子树的右子树压入堆栈,下一次循环会把右子树的所有左子树压入堆栈
}
}while(top != -1);
}
/*************************************
* 函数作用:树的前序遍历(非递归)
* 函数名:Preorder1
* 参数列表:BinTree bt
* 返回类型:void
*************************************/
void Preorder1(BinTree bt)
{
BinTNode *ST[100];//用指针数组来模拟栈
BinTNode *s = bt;//定义临时指针指向bt
int top = 0;//初始化栈顶指针
if(s!=NULL)//如果这棵树不是个空树
{
while(top>=0)
{
printf("%c",s->data);//访问节点
if(s->rchild!=NULL)
ST[top++] = s->rchild;//并把右子树压入堆栈
if(s->lchild!=NULL)
s = s->lchild;//s指向这棵树的左子树
else
s = ST[--top];
}
}
}
/*************************************
* 函数作用:树的后序遍历(非递归)
* 函数名:Postorder1
* 参数列表:BinTree bt
* 返回类型:void
*************************************/
void Postorder1(BinTree bt)
{
BinTNode *ST[100];//用指针数组来模拟栈
BinTNode *s = bt;//定义临时指针指向bt
int topl = 0,topr = 99;//初始化栈顶指针
if(s!=NULL)//如果这棵树不是个空树
{
while(topr<=99)
{
ST[topl++] = s;
if(s->lchild == NULL && s->rchild == NULL)
{
s = ST[++topr];
continue;
}
if(s->lchild!=NULL)
ST[topr--] = s->lchild;
if(s->rchild!=NULL)
s = s->rchild;
}
while(1)
{
--topl;
if(topl>=0)
printf("%c",ST[topl]->data);
else
break;
}
}
}
/*************************************
* 函数作用:树的层序遍历
* 函数名:TransLevel
* 参数列表:BinTree bt
* 返回类型:void
*************************************/
void TransLevel(BinTree bt)
{
BinTNode *ST[100];//用指针数组来模拟栈
BinTNode *s = bt;//定义临时指针指向bt
int h = 0,l = 0;
if(s!=NULL)//如果这棵树不是个空树
{
ST[l++] = s;
do{
s = ST[(h++)%100];
printf("%c",s->data);
if(s->lchild!=NULL)
ST[(l++)%100] = s->lchild;
if(s->rchild!=NULL)
ST[(l++)%100] = s->rchild;
}while(h != l);
}
}
/*************************************
* 函数作用:求树的深度
* 函数名:BinTreeDepth
* 参数列表:BinTree bt
* 返回类型:int
*************************************/
int BinTreeDepth(BinTree bt)
{
int LDepth = 0,RDepth = 0;
if(bt!=NULL)
{
if(bt->lchild!=NULL)
LDepth = BinTreeDepth(bt->lchild);
if(bt->rchild!=NULL)
RDepth = BinTreeDepth(bt->rchild);
return LDepth>RDepth?++LDepth:++RDepth;
}
else
{
return 0;
}
}
/*************************************
* 函数作用:在树中查找某元素
* 函数名:FindBT
* 参数列表:BinTree bt,DataType x
* 返回类型:BinTree
*************************************/
BinTree FindBT(BinTree bt,char x)
{
if(bt!=NULL)
{
BinTree l,r;
l = r = NULL;
if(bt->data == x)
return bt;
l = FindBT(bt->lchild,x);
r = FindBT(bt->rchild,x);
return l>r?l:r;
}
else
{
return NULL;
}
}
/*************************************
// if(test!=NULL)
// printf("%d",Level(h,test));
* 函数作用:在树中查找某节点所在层次
* 函数名:Level
* 参数列表:BinTree bt,BinTNode *p
* 返回类型:int
*************************************/
int Level(BinTree bt,BinTNode *p)
{
if(bt!=NULL)
{
if(bt == p)
return 1;
int l,r;
l = r = 0;
l = Level(bt->lchild,p);
r = Level(bt->rchild,p);
if(l == -1&& r == -1)
return -1;
else
return (l>r?l:r)+1;
}
return -1;
}
int main(int argc, char const *argv[])
{
//char a[] = "a(b,c(d(e,f),g))";
//BinTree h;
//h = CreateTree(a);
// h = CreateBinTree(h);
// Preorder(h);
// Inorder(h);
// Postorder(h);
// Inorder1(h);
// Preorder1(h);
// Postorder1(h);
// TransLevel(h);
// printf("%d",BinTreeDepth(h));
// BinTree test = FindBT(h,'k');
// if(test!=NULL)
// printf("%c",test->data);
// BinTree test = FindBT(h,'a');
// if(test!=NULL)
// printf("%d",Level(h,test));
return 0;
}
最全的二叉树数据结构算法
最新推荐文章于 2024-07-26 22:12:13 发布