二叉树的代码实现

二叉树的定义

二叉树(Binary Tree)是n(n≥0)个节点所构成的集合,它或为空树(n=0),或为非空树。对于非空树T:
(1)有且仅有一个称之为根的节点;
(2)除根节点以外的其余节点分为两个互不相交的子集T1和T2,分别称为T的左子树和右子树,且T1和T2本身又都是二叉树。
二叉树与树一样具有递归性质,二叉树与树的区别主要有以下两点:
(1)二叉树每个节点至多只有两棵子树(二叉树中不存在度大于2的节点);
(2)二叉树的子树有左右之分,其次序不能任意颠倒。
二叉树的递归定义表明二叉树或为空,或由一个根节点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。由于这两棵子树也是二叉树,则由二叉树的定义,它们也可以是空树。由此,二叉树可以有5种基本形态,如图5.3所示。

eb591a5b87e04ee7ba69d3f775e23007.jpeg

图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版 严蔚敏 李冬梅 吴伟民 编著)。如有疑问和建议可以在评论区留言,最后感谢大家的耐心阅读。谢谢大家。

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荧光百叶草

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值