二叉树的基本实现

摘要

一、定义和数据结构

1. 定义

  二叉树(Binary Tree)是一种树形结构,它的特点是每个结点至多有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能随意颠倒。

2. 数据结构

typedef struct BiTNode
{
    ElemType data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

  该结点是二叉树中最基本的元素,包括数据域和指针域。

二、初始化和赋值

1. 初始化

BiTree myBiTree; // 定义一个指向二叉树根结点的指针

InitTree(&myBiTree); // 初始化二叉树

  我们使用一个指向二叉树根结点的指针表示一颗二叉树。
  需要注意的是,二叉树的初始化InitTree改变的是根结点指针本身的内容,而不是指针指向的内容,所以在传递参数时,使用指针传递,传递根结点指针的指针,即根结点指针的地址。

Status InitTree(BiTree *T)
{
    // *T 即为指向二叉树根结点的指针.
    if (*T == NULL) // 若已经指向空, 操作失败, 报错.
    {
        return ERROR;
    }

    *T = NULL; // 使得指针指向 NULL.

    return OK;
} // InitTree

2. 赋值

  按照先序次序为二叉树结点赋值。

// ! *T是二叉树指针的指针, **T才是二叉树本体.
void CreateTree(BiTree *T, FILE *fp)
{
    char ch = 0;

    ch = fgetc(fp); // 从输入文件中读取一个字符.

    if (ch == '^') // 使用'^'表示空结点.
    {
        *T = NULL;
    }
    else
    {
        // 为根结点指针分配要指向要内存空间.
        *T = (BiTNode *)malloc(sizeof(BiTNode));
        if (!*T)
        {
            exit(OVERFLOW);
        }

        (*T)->data = ch;
        CreateTree(&((*T)->lchild), fp); // 递归创建左右子树.
        CreateTree(&((*T)->rchild), fp); // 依旧传递指针的指针.
    }
} // CreateTree

  在定义CreateTree时也可以不使用两层套娃, 但之所以仍像InitTree一样是因为:
    1. 保持一致性,凡是涉及到修改二叉树的操作,都传递指针的指针。
    2. 若以后修改二叉树的操作涉及对二叉树指针本身的修改,这么做可以减少麻烦。实际上CreateTree中的*T = NULL理解起来比&T = NULL方便.

三、遍历方式

  遍历不修改二叉树,直接传递指针。

1. 前序

Status PreOrderTraverse(BiTree T, Status (*Visit)(ElemType e))
{
    if (T)
    {
        if (Visit(T->data))
        {
            if (PreOrderTraverse(T->lchild, Visit))
            {
                if (PreOrderTraverse(T->rchild, Visit))
                {
                    return OK;
                }
            }
        }
        return ERROR;
    }
    else
    {
        return OK;
    }
} // PreOrderTraverse

2. 中序

Status InOrderTraverse(BiTree T, Status (*Visit)(ElemType e))
{
    if (T)
    {
        if (InOrderTraverse(T->lchild, Visit))
        {
            if (Visit(T->data))
            {
                if (InOrderTraverse(T->rchild, Visit))
                {
                    return OK;
                }
            }
        }
        return ERROR;
    }
    else
    {
        return OK;
    }
} // InOrderTraverse

3. 后序

Status PostOrderTraverse(BiTree T, Status (*Visit)(ElemType e))
{
    if (T)
    {
        if (PostOrderTraverse(T->lchild, Visit))
        {
            if (PostOrderTraverse(T->rchild, Visit))
            {
                if (Visit(T->data))
                {
                    return OK;
                }
            }
        }
        return ERROR;
    }
    else
    {
        return OK;
    }
} // PostOrderTraverse

参考文献

  1. 数据结构:C语言版/严蔚敏,吴伟民编著. ——北京:清华大学出版社,2007

代码仓库

  1. https://github.com/tianshihao/data-structure/tree/master/chapter_6
posted @ 2020-03-30 00:02  田世豪  阅读(354)  评论(0编辑  收藏  举报