眩しさだけは、忘れなかった。|

【数据结构-树】二叉树的相关算法

1 计算二叉树中双分支结点的个数

假设二叉树采用二叉链表存储,试设计一个算法,计算一棵给定二叉树的所有双分支结点个数。

int count = 0;

void Degree2 (BiTree T){
    if (T != NULL){
        Degree2(T->lchild);
        Degree2(T->rchild);
        if ((T->lchild != NULL) && (T->rchild != NULL))
            count++;   
    }
} 

2 交换二叉树中所有左右子树

编写一个把树 B 中所有结点的左、右子树进行交换的函数。

void SwapNodeChild (BiTree T){
    if (T->lchild != NULL)
        SwapNodeChild(T->lchild);
    if (T->rchild != NULL)
        SwapNodeChild(T->rchild);

    Swap(T->lchild, T->rchild);
}

3 求先序遍历第 k 个元素

设计一个算法,求先序遍历序列中第 k 个结点的值。

int i = 1;

int PreOrder (BiTree T, int k){
    if (T != NULL){
        if (i == k)
            return T->data;
        i++;
        
        PreOrder(T->lchild, k);
        PreOrder(T->rchild, k);
    }
}

4 删去值为 x 的子树

对于树中每个元素值为 x 的结点,删去以它为根的子树,并释放相应的空间。

void Delete (BiTree T){ // 找到元素值为 x 的结点后,递归删去它的左子树和右子树
    if (T != NULL){
        Delete(T->lchild);
        Delete(T->rchild);
        free(T);
    }
}

void Find (BiTree T, int x){
    if (T != NULL){
        if (T->data == x){ // 若找到元素值为 x 的结点
            Delete(T);     // 开始递归删去它的左子树和右子树
            return;
        }
        else{ // 若不是元素值为 x 的结点
            Find(T->lchild, x); // 继续找左子树中有无元素值为 x 的结点
            Find(T->rchild, x); // 继续找右子树中有无元素值为 x 的结点
        }
    }
}

5 计算二叉树的带权路径长度(WPL)

二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树 T,采用二叉链表存储结点结构为

left weight right
左子树指针域 权值 右子树指针域

其中叶结点的 weight 域保存该结点的非负权值,设 root 为指向 T 的根结点的指针,请设计求 T 的 WPL 的算法。

算法的核心思想是先序遍历 + 计算层数,代码如下:

int WPL;

void WPL_PreOrder (BiTree T, int level){
    if (T != NULL){
        if ((T->lchild != NULL) && (T->rchild != NULL))
            WPL = WPL + T->weight * level;
        else if ((T->lchild != NULL) && (T->rchild == NULL))
            WPL_PreOrder(T->lchild, level + 1);
        else
            WPL_PreOrder(T->rchild, level + 1);
    }
}

// main 函数中调用:
WPL_PreOrder(Tree, 0);

6 将表达式树转化为等价的中缀表达式

请设计一个算法,将给定的表达式树,转换成等价的中缀表达式并输出。

二叉树结点定义如下:

typedef struct node{
    char data[10];
    struct node *left, * right;
} BTree;

算法的核心思想是中序遍历 + 计算层数。可以先将中序遍历的表达式先写出来,再与加了括号的表达式对比一下,看看哪个地方加了括号。遍历左子树前加上左括号,遍历完右子树后加上右括号,根结点(表达式最外层)和叶结点(操作数)不需要加括号。代码如下:

void InOrder (BTree *T, int level){
    if (T != NULL){
        if ((T->left == NULL) && (T->right == NULL)) // 叶结点
            输出 T->data; // 输出操作数
        else{
            if (level > 1) // 若有子表达式则加 1 层括号
                输出 "(";
            InOrder(T->left, level + 1);
            输出 T->data; // 输出操作符
            InOrder(T->right, level + 1);
            if (level > 1) // 若有子表达式则加 1 层括号
                输出 ")";
        }
    }
}

// main 函数中调用:
InOrder(Tree, 0);

本文作者:漫舞八月(Mount256)

本文链接:https://www.cnblogs.com/Mount256/p/16977148.html

版权声明:本作品采用CC 4.0 BY-SA许可协议进行许可。

posted @   漫舞八月(Mount256)  阅读(217)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开
  1. 1 Main Menu Theme Syd Matters
  2. 2 Luminous Memory (Acyanxi Remix) Acyanxi
  3. 3 夏影 麻枝准
  4. 4 潮騒の香り 水月陵
  5. 5 stand still 井口裕香 (いぐち ゆか)
  6. 6 流星雨 麻枝准
  7. 7 Summer Fantasy 傅许
  8. 8 失う 米白
  9. 9 epilogue 霜月はるか
  10. 10 夏に君を待ちながら 小原好美
  11. 11 桜のような恋でした 鹿乃 (かの)
  12. 12 風は微かに、熱を残し… 水月陵
  13. 13 夏凪ぎ 麻枝准/やなぎなぎ
  14. 14 空に光る 戸越まごめ
  15. 15 木漏れ日 riya
  16. 16 Songbirds Homecomings (ホームカミングス)
  17. 17 宝物になった日 麻枝准/やなぎなぎ
  18. 18 夏影~あの飛行機雲を超えた、その先へ~ 雪桜草 (雪樱草)
  19. 19 快晴 Orangestar (蜜柑星P),初音未来 (初音ミク)
  20. 20 永遠 霜月はるか
  21. 21 Sion 天門
  22. 22 遙かな年月-piano- 麻枝准
  23. 23 夏恋慕 kobasolo/春茶
  24. 24 夏凪ぎ-piano ver.- MANYO/麻枝准
  25. 25 Goodbye Seven Seas -piano ver.- MANYO/麻枝准
  26. 26 Light Years 麻枝准/やなぎなぎ
  27. 27 優しさの記憶 鹿乃 (かの)
Main Menu Theme - Syd Matters
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.