树与森林的基本操作

目录

一、树的遍历

1.1 先根遍历

1.1.1 算法思想

1.1.2 算法实现 

1.2 后根遍历

1.2.1 算法思想

1.2.2 算法实现

二、树的遍历算法应用

2.1 树的创建

2.2 树的销毁

三、森林的遍历 

3.1 先序遍历

3.1.1 算法思想

3.1.2 算法实现

3.2 中序遍历

3.2.1 算法思想 

3.2.2 算法实现

3.3 后序遍历

3.3.1 算法思想

3.3.2 算法实现

四、森林的遍历算法应用

4.1 森林的创建

4.2 森林的销毁 


一、树的遍历

1.1 先根遍历

1.1.1 算法思想

若树非空,则遍历方法为:

1、访问根结点;

2、从左到右,依次先根遍历根结点的每一棵子树。

树的先根遍历 <=> 转换后二叉树的先序遍历

如图所示:

1.1.2 算法实现 

/* 先根遍历 */
void RootFirst(CSTree root, CALLBACK Visit) {
    if (!root) return;

    Visit(root->data);
    RootFirst(root->FirstChild, Visit);
    RootFirst(root->NextSibling, Visit);
}

1.2 后根遍历

1.2.1 算法思想

若树非空,则遍历方法为:

1、从左到右,依次后根遍历根结点的每一棵子树;

2、访问根结点。

树的后根遍历 <=> 转换后二叉树的中序遍历 

如图所示:

1.2.2 算法实现

/* 后根遍历 */
void RootLast(CSTree root, CALLBACK Visit) {
    if (!root) return;

    RootLast(root->FirstChild, Visit);
    Visit(root->data);
    RootLast(root->NextSibling, Visit);
}

二、树的遍历算法应用

2.1 树的创建

根据先根/先序定位串创建树。

CSTree _CreateCSTree(char **s) {
    if (**s == '\0') return NULL;

    if (**s == '.') {
        ++ *s;
        return NULL;
    }

    CSTree root = (CSTree)malloc(sizeof(CSNode));
    root->data.tag = **s;
    
    ++ *s;
    root->FirstChild = _CreateCSTree(s);
    root->NextSibling = _CreateCSTree(s);

    return root;
}

2.2 树的销毁

 后序遍历销毁树。

void DestroyCSTree(CSTree root) {
    if (!root) return;

    DestroyCSTree(root->FirstChild);
    DestroyCSTree(root->NextSibling);
    free(root);
}

三、森林的遍历 

对照二叉树与森林之间的转换关系可以发现,森林的先序遍历、中序遍历和后序遍历与其相应二叉树的先序遍历、中序遍历和后序遍历是对应相同的。因此,对森林的遍历可以转换为对其相应二叉树的遍历。

示例:

3.1 先序遍历

3.1.1 算法思想

若森林非空,则遍历方法为:

1、访问森林中第一棵树的根结点;

2、先序遍历第一棵树的根结点的子树森林;

3、先序遍历除去第一棵树之后剩余的树构成的森林。

3.1.2 算法实现

/* 先序遍历 */
void ForestPre(Forest f, CALLBACK visit) {
    if (!f) return;

    visit(f->data);
    ForestPre(f->FirstChild, visit);
    ForestPre(f->NextSibling, visit);
}

3.2 中序遍历

3.2.1 算法思想 

若森林非空,则遍历方法为:

1、中序遍历第一棵树的根结点的子树森林;

2、访问森林中第一棵树的根结点;

3、中序遍历除去第一棵树之后剩余的树构成的森林。

3.2.2 算法实现

/* 中序遍历 */
void ForestIn(Forest f, CALLBACK visit) {
    if (!f) return;

    ForestIn(f->FirstChild, visit);
    visit(f->data);
    ForestIn(f->NextSibling, visit);
}

3.3 后序遍历

3.3.1 算法思想

 若森林非空,则遍历方法为:

1、后序遍历第一棵树的根结点的子树森林;

2、后序遍历除去第一棵树之后剩余的树构成的森林;

3、访问森林中第一棵树的根结点。

3.3.2 算法实现

/* 后序遍历 */
void ForestPost(Forest f, CALLBACK visit) {
    if (!f) return;
    
    ForestPost(f->FirstChild, visit);
    ForestPost(f->NextSibling, visit);
    visit(f->data);
}

四、森林的遍历算法应用

4.1 森林的创建

示意图:

Forest CreateForest(char *f[], int n) {
    Forest forest;

    /* 生成新森林 */
    forest = (Forest)malloc(sizeof(CSNode));
    forest->NextSibling = NULL;

    CSTree t;
    for (int i = 0; i < n; ++i) {
        CSTree root = CreateCSTree(f[i]);
        if (i == 0)
            forest->FirstChild = root;
        else
            t->NextSibling = root;
        t = root;
    }

    return forest;
}

4.2 森林的销毁 

 森林就相当于一棵树。

void DestroyForest(Forest f) {
    DestroyCSTree(f);
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值