二叉树的定义
二叉树(Binary Tree)是n(n≥0)个节点所构成的集合,它或为空树(n=0),或为非空树。对于非空树T:
(1)有且仅有一个称之为根的节点;
(2)除根节点以外的其余节点分为两个互不相交的子集T1和T2,分别称为T的左子树和右子树,且T1和T2本身又都是二叉树。
二叉树与树一样具有递归性质,二叉树与树的区别主要有以下两点:
(1)二叉树每个节点至多只有两棵子树(二叉树中不存在度大于2的节点);
(2)二叉树的子树有左右之分,其次序不能任意颠倒。
二叉树的递归定义表明二叉树或为空,或由一个根节点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。由于这两棵子树也是二叉树,则由二叉树的定义,它们也可以是空树。由此,二叉树可以有5种基本形态,如图5.3所示。
图5.3
二叉树的性质
二叉树具有下列重要特性。
性质1 在二叉树的第i层上至多有2^i-1(i≥1)个节点
证明:利用归纳法容易证得此性质。
i=1时,只有一个根节点。显然,2^i-1=2^0=1是对的。
现在假定对所有的j(1≤i<i)命题成立,即第j层上至多有2^i-1节点。那么,可以证明j=i时命题也成立。
由归纳假设:第i-1层上至多有2^i-2个节点。由于二叉树每个节点的度至多为2,故在第i层上的最大节点数为在第i-1层上的最大节点数的2倍,即2x2^i-2=2^i-1。
性质2 深度为k的二叉树至多有2k-1(k≥1)个节点。
证明:由性质1可见,深度为k的二叉树的最大节点数为:
∑(第i层上的最大结点数)=∑2^i-1=2^k-1
性质3 对任何一棵二叉树T,如果其终端节点数为n0,度为2的节点数为n2,则n0=n2+1。
证明:设n1为二叉树T中度为1的节点数。因为二叉树中所有节点的度均小于或等于2,所以其节点总数为:
n=n0+n1+n2(5-1)
再看二叉树中的分支数。除了根节点外,其余节点都有一个分支进入,设B为分支总数,则n=B+1。由于这些分支是由度为1或2的节点射出的,因此又有B=n1+2n2。
于是得:
n=n1+2n+1(5-2)
由式(5-1)和式(5-2)得:
n0=n2+1
现在介绍两种特殊形态的二叉树,它们是满二叉树和完全二叉树。
满二叉树:深度为k且含有2^k-1个节点的二叉树。
满二叉树的特点是:每一层上的节点数都是最大节点数,即每一层的节点数都具有最大值2^i-1。
可以对满二叉树的节点进行连续编号,约定编号从根节点起,自上而下,自左至右。由此可引出完全二叉树的定义。
完全二叉树:深度为k的、有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中编号从1至n的节点一一对应时,称之为完全二叉树。
完全二叉树的特点是:
(1)、叶子节点只可能在层次最大的两层上出现;
(2) 、对任一节点,若其右分支下的子孙的最大层次为l,则其左分支下的子孙的最大层次必为l或l+1。
完全二叉树在很多场合下出现,下面的性质4和性质5是完全二叉树的两个重要特性。
性质4 具有n个节点的完全二叉树的深度为⌊log2n⌋ +1。
证明:假设深度为k,则根据性质2和完全二叉树的定义有
2^(k-1)-1<n≤2^k-1或 2^k-1≤n<2^k
于是k-1≤log2n<k,因为k是整数,所以k=⌊log2n⌋+1。
性质 5如果对一棵有n个节点的完全二叉树(其深度为⌊log2n⌋ +1)的节点按层序编号(从第1层到第⌊log2n⌋ +1层,每层从左到右),则对任一节点i(1≤i≤n),以下结论成立。
(1)如果i=1,则节点i是二叉树的根,无双亲;如果i>1,则其双亲PARENT(i)是节点⌊i/2⌋ 。
(2)如果2i>n,则节点i无左孩子(节点i为叶子节点);否则其左孩子LCHILD(i)是节点2i。
(3)如果2i+1>n,则节点i无右孩子;否则其右孩子RCHILD(i)是节点2i+1。
二叉树的代码实现(C语言)
二叉树的相关定义和存储结构
#define TRUE 1
#define FALSE -1
typedef char ElemType;
typedef struct B_Node
{
struct B_Node *left;
struct B_Node *right;
ElemType elem;
}BtNode,*Btree;
二叉树的初始化算法
算法描述:动态申请一块树节点大小的内存空间。并填充该节点的数据域elem和指针域left_child、right_child。
int InitBiTree(Btree *tree,ElemType elem,ElemType left_child,ElemType right_child)
{
if(elem=='#')
{
return FALSE;
}
BtNode *summon=(BtNode*)malloc(sizeof(BtNode)),*left=NULL,*right=NULL;
if(summon==NULL)
{
return FALSE;
}
else {
if(left_child!='#')
{
left=(BtNode*)malloc(sizeof(BtNode));
left->elem=left_child;
left->left=NULL;
left->right=NULL;
}
else
{
left=NULL;
}
if(right_child!='#')
{
right=(BtNode*)malloc(sizeof(BtNode));
right->elem=right_child;
right->left=NULL;
right->right=NULL;
}
else
{
right=NULL;
}
summon->elem=elem;
summon->left=left;
summon->right=right;
(*tree)=summon;
return TRUE;
}
}
二叉树的销毁与清理算法
算法描述:先递归每个不为空的节点。然后再释放该节点所在的内存空间。最后把指向该节点的指针置空。
void DestroyBiTree(Btree *root)
{
if((*root)!=NULL)
{
DestroyBiTree(&(*root)->left);
DestroyBiTree(&(*root)->right);
free((*root));
(*root)=NULL;
}
}
void ClearBiTree(Btree *root)
{
if((*root)!=NULL)
{
DestroyBiTree(&(*root)->left);
DestroyBiTree(&(*root)->right);
free((*root));
(*root)=NULL;
}
}
判断该节点是否为空树的算法
算法描述:判断传递过来的指针参数指向的地址是否为空。如果为空则该节点对应的二叉树为空树,不为空则该节点对应的二叉树不为空。
int BiTreeEmpty(Btree *tree)
{
if((*tree)==NULL)
{
return TRUE;
}
else
{
return FALSE;
}
}
求二叉树的深度算法
算法描述:递归遍历每个节点的左子树和右子树。用left和right分别记录遍历过的节点数量(自增1),然后left和right比较大小并把数值最大的变量赋值给max。最后返回变量max。
int BiTreeDepth(Btree *tree)
{
int max=0;
int left=0;
int right=0;
if((*tree)==NULL)
{
return 0;
}
else
{
left=BiTreeDepth(&(*tree)->left)+1;
if(left>max)
{
max=left;
}
right=BiTreeDepth(&(*tree)->right)+1;
if(right>max)
{
max=right;
}
}
return max;
}
求二叉树的根节点算法
算法描述:判断传递过来的参数tree的指向地址是否为空。如果不为空则返回该节点的数据域elem,否则返回空。
ElemType Root(Btree *tree)
{
if((*tree)!=NULL)
{
return (*tree)->elem;
}
else
{
return NULL;
}
}
获取指定节点的算法
算法描述:递归遍历二叉树并比较参数elem和每个节点对应的数据域。用新建立的空节点result指向遍历后返回的节点数据。如果返回的节点为空(表示参数elem的值与二叉树每个节点对应的数据域的值都不相等)则返回空,否则返回与elem参数相等的数据域对应的节点。
Btree Value(Btree *tree,ElemType elem)
{
Btree result=NULL;
if((*tree)==NULL)
{
return NULL;
}
else if((*tree)->elem==elem)
{
return (*tree);
}
else if((*tree)->elem!=elem)
{
if(Value(&(*tree)->left,elem)!=NULL)
{
result=Value(&(*tree)->left,elem);
}
else if(Value(&(*tree)->right,elem)!=NULL)
{
result=Value(&(*tree)->right,elem);
}
}
return result;
}
修改节点数据域的算法
算法描述:递归遍历二叉树并比较参数elem和每个节点对应的数据域对应的值。如果相等则把参数value的值赋值给与参数elem相等的节点对应的数据域并返回条件为真(TRUE),否则一直遍历该二叉树直到二叉树的指针域为空。
int Assign(Btree *tree,ElemType elem,ElemType value)
{
int result=FALSE;
if((*tree)==NULL)
{
return FALSE;
}
else if((*tree)->elem==elem)
{
(*tree)->elem=value;
return TRUE;
}
else
{
result=Value(&(*tree)->left,elem);
result=Value(&(*tree)->right,elem);
}
return result;
}
获取双亲节点的算法
算法描述:建立辅助队列数据类型:Queue_Of_BTNode。其中内部的成员变量collection为一个大小默认为255个二叉树节点变量所在内存的空间大小。front用来指向队列的队头元素、rear用来指向队列的队尾元素。初始化时将成员变量front和rear赋值为0。成员变量collection数组对应的每个队列元素赋值为空。将二叉树节点对应的地址分别写入成员指针变量collection数组的每个队列元素。然后遍历写入数据后的成员指针变量collection中的每个数组下标对应的地址,判断该地址对应的树节点是否等于参数elem,如果相等就用结构体指针target指向该节点,否则就一直遍历成员变量collection数组直到rear下标对应的collection数组元素。
ElemType Parent(Btree *tree,ElemType elem)
{
BtNode *p=(*tree),*target=NULL;
int max_size_of_queue=255;
struct
{
Btree *collection;
int front;
int rear;
}Queue_Of_BTNode;
Queue_Of_BTNode.front=0;
Queue_Of_BTNode.rear=0;
Queue_Of_BTNode.collection=(BtNode*)malloc(sizeof(BtNode)*max_size_of_queue);
if(Queue_Of_BTNode.collection==NULL)
{
return FALSE;
}
else
{
for(int i=0;i<max_size_of_queue;i++)
{
Queue_Of_BTNode.collection[i]=NULL;
}
if(p!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p;
++Queue_Of_BTNode.rear;
while(p!=NULL)
{
if(p->left!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->left;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
if(p->right!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->right;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
++Queue_Of_BTNode.front;
p=Queue_Of_BTNode.collection[Queue_Of_BTNode.front];
}
for(int i=0;i<Queue_Of_BTNode.rear;i++)
{
if(Queue_Of_BTNode.collection[i]!=NULL)
{
if(Queue_Of_BTNode.collection[i]->elem==elem)
{
target=Queue_Of_BTNode.collection[i];
break;
}
else
{
continue;
}
}
}
if(target==NULL)
{
return FALSE;
}
for(int i=0;i<Queue_Of_BTNode.rear;i++)
{
if(Queue_Of_BTNode.collection[i]!=NULL)
{
if(Queue_Of_BTNode.collection[i]->left==target||Queue_Of_BTNode.collection[i]->right==target)
{
return Queue_Of_BTNode.collection[i]->elem;
}
}
}
}
free(Queue_Of_BTNode.collection);
Queue_Of_BTNode.collection=NULL;
Queue_Of_BTNode.rear=NULL;
Queue_Of_BTNode.front=NULL;
}
return FALSE;
}
获取左右子树的算法
算法描述:略,与获取指定节点的算法和修改节点数据域的算法类似。
ElemType LeftChild(Btree *tree,ElemType elem)
{
ElemType receive=NULL;
if((*tree)==NULL)
{
return NULL;
}
else if((*tree)->elem==elem&&(*tree)->left!=NULL)
{
return (*tree)->left->elem;
}
else
{
if(LeftChild(&(*tree)->left,elem)!=NULL)
{
receive=LeftChild(&(*tree)->left,elem);
}
if(LeftChild(&(*tree)->right,elem)!=NULL)
{
receive=LeftChild(&(*tree)->right,elem);
}
}
return receive;
}
ElemType RightChild(Btree *tree,ElemType elem)
{
ElemType receive=NULL;
if((*tree)==NULL)
{
return NULL;
}
else if((*tree)->elem==elem&&(*tree)->right!=NULL)
{
return (*tree)->right->elem;
}
else
{
if(RightChild(&(*tree)->left,elem)!=NULL)
{
receive=RightChild(&(*tree)->left,elem);
}
if(RightChild(&(*tree)->right,elem)!=NULL)
{
receive=RightChild(&(*tree)->right,elem);
}
}
return receive;
}
获取左右兄弟节点的算法
算法描述:略,与获取父节点的算法类似。
ElemType LeftSibLing(Btree *tree,ElemType elem)
{
BtNode *p=(*tree),*target=NULL;
int max_size_of_queue=255;
struct
{
Btree *collection;
int front;
int rear;
}Queue_Of_BTNode;
Queue_Of_BTNode.front=0;
Queue_Of_BTNode.rear=0;
Queue_Of_BTNode.collection=(BtNode*)malloc(sizeof(BtNode)*max_size_of_queue);
if(Queue_Of_BTNode.collection==NULL)
{
//do nothing
}
else
{
for(int i=0;i<max_size_of_queue;i++)
{
Queue_Of_BTNode.collection[i]=NULL;
}
if(p!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p;
++Queue_Of_BTNode.rear;
while(p!=NULL)
{
if(p->left!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->left;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
if(p->right!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->right;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
++Queue_Of_BTNode.front;
p=Queue_Of_BTNode.collection[Queue_Of_BTNode.front];
}
for(int i=0;i<Queue_Of_BTNode.rear;i++)
{
if(Queue_Of_BTNode.collection[i]!=NULL)
{
if(Queue_Of_BTNode.collection[i]->elem==elem)
{
target=Queue_Of_BTNode.collection[i];
break;
}
}
else
{
//Do nothing!
}
}
if(target==NULL)
{
return FALSE;
}
for(int i=0;i<Queue_Of_BTNode.rear;i++)
{
if(Queue_Of_BTNode.collection[i]!=NULL)
{
if(Queue_Of_BTNode.collection[i]->right==target)
{
return Queue_Of_BTNode.collection[i]->left->elem;
}
}
else
{
//Do nothing!
}
}
}
free(Queue_Of_BTNode.collection);
Queue_Of_BTNode.collection=NULL;
Queue_Of_BTNode.rear=NULL;
Queue_Of_BTNode.front=NULL;
}
return FALSE;
}
ElemType RightSibLing(Btree *tree,ElemType elem)
{
BtNode *p=(*tree),*target=NULL;
int max_size_of_queue=255;
struct
{
Btree *collection;
int front;
int rear;
}Queue_Of_BTNode;
Queue_Of_BTNode.front=0;
Queue_Of_BTNode.rear=0;
Queue_Of_BTNode.collection=(BtNode*)malloc(sizeof(BtNode)*max_size_of_queue);
if(Queue_Of_BTNode.collection==NULL)
{
//do nothing
}
else
{
for(int i=0;i<max_size_of_queue;i++)
{
Queue_Of_BTNode.collection[i]=NULL;
}
if(p!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p;
++Queue_Of_BTNode.rear;
while(p!=NULL)
{
if(p->left!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->left;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
if(p->right!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->right;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
++Queue_Of_BTNode.front;
p=Queue_Of_BTNode.collection[Queue_Of_BTNode.front];
}
for(int i=0;i<Queue_Of_BTNode.rear;i++)
{
if(Queue_Of_BTNode.collection[i]!=NULL)
{
if(Queue_Of_BTNode.collection[i]->elem==elem)
{
target=Queue_Of_BTNode.collection[i];
break;
}
}
else
{
continue;
}
}
if(target==NULL)
{
return FALSE;
}
for(int i=0;i<Queue_Of_BTNode.rear;i++)
{
if(Queue_Of_BTNode.collection[i]!=NULL)
{
if(Queue_Of_BTNode.collection[i]->left==target)
{
return Queue_Of_BTNode.collection[i]->right->elem;
}
}
}
}
free(Queue_Of_BTNode.collection);
Queue_Of_BTNode.collection=NULL;
Queue_Of_BTNode.rear=NULL;
Queue_Of_BTNode.front=NULL;
}
return FALSE;
}
二叉树节点的插入算法(建议与获取指定节点的算法配合使用!)
算法描述:先判断插入节点的位置(tag为0表示插入左子树,tag为1表示插入右子树)。然后根据要插入的位置判断结构体指针参数parent对应的节点域是否为空,如果为空就把新建立的节点summon插入到对应位置,如果不为空则先修改summon对应的指针域。然后再把parent对应的指针域修改指向summon。
int InsertChild(Btree *parent,ElemType child,unsigned int tag) //should insert elemtype not btree
{
//0 represents left child
//1 represents right child
if(tag==0)
{
BtNode *summon=(BtNode*)malloc(sizeof(BtNode));
if(summon==NULL)
{
return FALSE;
}
else
{
summon->elem=child;
if((*parent)->left!=NULL)
{
summon->left=(*parent)->left;
(*parent)->left=summon;
summon->right=NULL;
}
else
{
(*parent)->left=summon;
summon->left=NULL;
summon->right=NULL;
}
}
}
else if(tag==1)
{
BtNode *summon=(BtNode*)malloc(sizeof(BtNode));
if(summon==NULL)
{
return FALSE;
}
else
{
summon->elem=child;
if((*parent)->right!=NULL)
{
summon->right=(*parent)->right;
(*parent)->right=summon;
summon->left=NULL;
}
else
{
(*parent)->right=summon;
summon->left=NULL;
summon->right=NULL;
}
}
}
return TRUE;
}
树节点的删除算法
算法描述:略,与二叉树节点的插入算法类似。
int DeleteChild(Btree *tree,ElemType parent,unsigned int tag)
{
//0 represents left child
//1 represents right child
Btree Get_Node=NULL;
Get_Node=Value(&(*tree),parent);
if(Get_Node==NULL)
{
return FALSE;
}
else
{
if(tag==0)
{
DestroyBiTree(&Get_Node->left);
}
else if(tag==1)
{
DestroyBiTree(&Get_Node->right);
}
return TRUE;
}
}
二叉树的层次遍历算法
算法描述:略,与获取左右兄弟节点的算法类似。
void LevelTraverse(Btree *tree)
{
BtNode *p=(*tree);
int max_size_of_queue=255;
struct
{
Btree *collection;
int front;
int rear;
}Queue_Of_BTNode;
Queue_Of_BTNode.front=0;
Queue_Of_BTNode.rear=0;
Queue_Of_BTNode.collection=(BtNode*)malloc(sizeof(BtNode)*max_size_of_queue);
if(Queue_Of_BTNode.collection==NULL)
{
//do nothing
}
else
{
for(int i=0;i<max_size_of_queue;i++)
{
Queue_Of_BTNode.collection[i]=NULL;
}
if(p!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p;
++Queue_Of_BTNode.rear;
while(p!=NULL)
{
if(p->left!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->left;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
if(p->right!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->right;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
++Queue_Of_BTNode.front;
p=Queue_Of_BTNode.collection[Queue_Of_BTNode.front];
}
for(int i=0;i<Queue_Of_BTNode.rear;i++)
{
if(Queue_Of_BTNode.collection[i]!=NULL)
{
printf("%c\t",Queue_Of_BTNode.collection[i]->elem);
}
else
{
printf("#\t");
}
}
printf("\n");
}
free(Queue_Of_BTNode.collection);
Queue_Of_BTNode.collection=NULL;
Queue_Of_BTNode.rear=NULL;
Queue_Of_BTNode.front=NULL;
}
}
二叉树的先序遍历算法
算法描述:先输出tree结构体指针变量对应的数据域,然后再递归遍历左子树,最后遍历右子树。
void PreOrderTraverse(Btree *tree)
{
if((*tree)!=NULL)
{
printf("%c\t",(*tree)->elem);
PreOrderTraverse(&(*tree)->left);
PreOrderTraverse(&(*tree)->right);
}
}
二叉树的中序遍历算法
算法描述:略,与二叉树的先序遍历算法类似(改变了输出语句的顺序)。
void InOrderTraverse(Btree *tree)
{
if((*tree)!=NULL)
{
InOrderTraverse(&(*tree)->left);
printf("%c\t",(*tree)->elem);
InOrderTraverse(&(*tree)->right);
}
}
二叉树的后序遍历算法
算法描述:略,与二叉树的中序遍历算法类似(改变了输出语句的顺序)。
void PostOrderTraverse(Btree *tree)
{
if((*tree)!=NULL)
{
PostOrderTraverse(&(*tree)->left);
PostOrderTraverse(&(*tree)->right);
printf("%c\t",(*tree)->elem);
}
}
获取非空节点的个数算法
算法描述:略,与二叉树的层次遍历算法类似。
int BiTreeNodeNums(Btree *tree)
{
int counter=0;
BtNode *p=(*tree);
int max_size_of_queue=255;
struct
{
Btree *collection;
int front;
int rear;
}Queue_Of_BTNode;
Queue_Of_BTNode.front=0;
Queue_Of_BTNode.rear=0;
Queue_Of_BTNode.collection=(BtNode*)malloc(sizeof(BtNode)*max_size_of_queue);
if(Queue_Of_BTNode.collection==NULL)
{
return FALSE;
}
else
{
for(int i=0;i<max_size_of_queue;i++)
{
Queue_Of_BTNode.collection[i]=NULL;
}
if(p!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p;
++Queue_Of_BTNode.rear;
while(p!=NULL)
{
if(p->left!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->left;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
if(p->right!=NULL)
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=p->right;
++Queue_Of_BTNode.rear;
}
else
{
Queue_Of_BTNode.collection[Queue_Of_BTNode.rear]=NULL;
}
++Queue_Of_BTNode.front;
p=Queue_Of_BTNode.collection[Queue_Of_BTNode.front];
}
for(int i=0;i<Queue_Of_BTNode.rear;i++)
{
if(Queue_Of_BTNode.collection[i]!=NULL)
{
counter++;
}
else
{
printf("#\t");
}
}
printf("\n");
}
free(Queue_Of_BTNode.collection);
Queue_Of_BTNode.collection=NULL;
Queue_Of_BTNode.rear=NULL;
Queue_Of_BTNode.front=NULL;
return counter;
}
}
二叉树的生成树算法
算法描述:略,对应获取非空节点的个数算法。构造一个由receive、front、rear组成的队列。然后根据队列的信息动态构造二叉树。
Btree CreateBiTree(ElemType receive[])
{
int counter=0;
int max_size_of_queue=255;
unsigned int front=0;
unsigned int rear=0;
BtNode *containter[max_size_of_queue];
for(int i=0;i<max_size_of_queue;i++)
{
containter[i]=NULL;
}
while(receive[counter]!='\0')
{
if(receive[counter]=='#')
{
containter[counter]=NULL;
}
else
{
InitBiTree(&containter[counter],receive[counter],'#','#');
}
counter++;
}
while(front<counter)
{
if(containter[front]!=NULL)
{
++rear;
containter[front]->left=containter[rear];
++rear;
containter[front]->right=containter[rear];
}
else
{
rear+=2;
}
front++;
}
return *containter;
}
以上就是我个人的二叉树数据结构讲解与算法实现。讲解部分和ADT参考数据结构(C语言版 第2版 严蔚敏 李冬梅 吴伟民 编著)。如有疑问和建议可以在评论区留言,最后感谢大家的耐心阅读。谢谢大家。