二叉树_链式存储_遍历

摘要

  • 定义和数据结构
  • 初始化和赋值
  • 遍历方式

定义和数据结构

  1. 定义
    二叉树(Binary Tree)是一种树形结构,它的特点是每个结点至多有两棵子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能随意颠倒。
  2. 数据结构
typedef struct BiTNode
{
    ElemType data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

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

初始化和赋值

初始化

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

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

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

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

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

        return OK;
    } // InitTree

赋值

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

// ! *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一样是因为:

  • 保持一致性,凡是涉及到修改二叉树的操作,都传递指针的指针。
  • 若以后修改二叉树的操作涉及对二叉树指针本身的修改,这么做可以减少麻烦。实际上CreateTree中的*T = NULL理解起来比&T = NULL方便.

遍历方式

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

前序

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

中序

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

后序

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

你可能感兴趣的:(二叉树_链式存储_遍历)