• 深信服入职前编码训练21题--02


    题目描述:

    有一个节点数组,需要创建一棵最优二叉树,即每个节点的权值乘以节点在树中的长度,然后相加得到的值最小。以下图一为例,节点数组的[A,B,C,D,E]的权值分别为[15,7,6,6,5],构建好的最优二叉树见下图。
     
    相关代码如下,请补充缺失部分。
     
    ```
    struct node {
      int left, right, parent;
      int val;
    };
    int build_tree(struct node arr[], int cnt)
    {
      while (1) {
        int i;
        int min1 = -1;              //权值最小的节点编号
        int min2 = -1;              //权值第二小的节点编号
        int root_node = 0;          //根节点(没有父节点)的个数
     
        for (i = 0; i < cnt; ++i) {
          if (arr[i].____________ >= 0)
            continue;
          ++root_node;
          if (min1 < 0) {
            min1 = i;
          } else if (arr[i].val < ____________) {
            min2 = min1;
            min1 = i;
          } else if (min2 < 0) {
            min2 = i;
          } else if (arr[i].val < ____________) {
            min2 = i;
          }
        }
        if (root_node < ____________)
          break;
        arr[cnt].left = min2;
        arr[cnt].right = min1;
        arr[cnt].val = arr[min1].val + ____________;
        arr[cnt].parent = -1;
        arr[min1].parent = cnt;
        arr[min2].parent = cnt;
        ++cnt;
      }
      return cnt;
    }
     
    ```

    输入描述:

    第一行为数据个数 第二行为权值(整数)

    输出描述:

    构建的二叉树(用于绘图软件生成对应的二叉树图形)
    示例1
    输入
    
    5
    15 7 6 6 5
    
    输出
    
    ```mermaid
    graph TD
        n0[n0:15]
        n0 --> n8
        n1[n1:7]
        n1 --> n6
        n2[n2:6]
        n2 --> n5
        n3[n3:6]
        n3 --> n6
        n4[n4:5]
        n4 --> n5
        n5((11))
        n5 --> n7
        n6((13))
        n6 --> n7
        n7((24))
        n7 --> n8
        n8((39))
    ```
    
    说明
    1.grath TD下面的输出都是	开头
    2.n0 ---> n8 的意思是n0的父节点是n8

    分析:这道题是典型的哈夫曼树的构造,只需补充完树的构建部分即可。

    解答:

      1 #include <stdio.h>
      2 #include <limits.h>
      3 #include <assert.h>
      4 #include <malloc.h>
      5 
      6 struct node {
      7     int left, right, parent;
      8     int val;
      9 };
     10 
     11 void tree_print(const struct node arr[], int cnt)
     12 {
     13     int i;
     14     for (i = 0; i < cnt; ++i) {
     15         fprintf(stderr, "%d: {left:%d,right:%d,parent:%d,val:%d}
    "
     16             , i, arr[i].left, arr[i].right, arr[i].parent, arr[i].val);
     17     }
     18 }
     19 
     20 void tree_output(FILE *fp, const struct node arr[], int old_cnt, int cnt)
     21 {
     22     int i;
     23     fprintf(fp, "```mermaid
    ");
     24     fprintf(fp, "graph TD
    ");
     25     for (i = 0; i < cnt; ++i) {
     26         if (i < old_cnt)
     27             fprintf(fp, "	n%d[n%d:%d]
    ", i, i, arr[i].val);
     28         else
     29             fprintf(fp, "	n%d((%d))
    ", i, arr[i].val);
     30 
     31         if (arr[i].parent >= 0) {
     32             fprintf(fp, "	n%d --> n%d
    ", i, arr[i].parent);
     33         }
     34     }
     35     fprintf(fp, "```
    ");
     36 }
     37 
     38 int build_tree(struct node arr[], int cnt);
     39 
     40 static int input(int **arr, int *size)
     41 {
     42     int i;
     43     int ret;
     44 
     45     ret = fscanf(stdin, "%d
    ", size);
     46     if (ret != 1)
     47         return -1;
     48     if (*size <= 0)
     49         return -1;
     50     *arr = (int *)malloc(sizeof(int) * (*size));
     51     for (i = 0; i < *size; ++i) {
     52         fscanf(stdin, "%d ", &(*arr)[i]);
     53     }
     54     return 0;
     55 }
     56 int main(int argc, char *argv[])
     57 {
     58     int *vals = NULL;
     59     int cnt = 0;
     60     struct node *arr;
     61     int i;
     62 
     63     if (input(&vals, &cnt) < 0) {
     64         fprintf(stderr, "input error
    ");
     65         return 0;
     66     }
     67     arr = (struct node *)malloc(sizeof(struct node) * cnt * 3);
     68 
     69     for (i = 0; i < cnt; ++i) {
     70         arr[i].left = -1;
     71         arr[i].right = -1;
     72         arr[i].parent = -1;
     73         arr[i].val = vals[i];
     74     }
     75 
     76     int newcnt = build_tree(arr, cnt);
     77     tree_output(stdout, arr, cnt, newcnt);
     78     free(vals);
     79     free(arr);
     80     return 0;
     81 }
     82 
     83 //  建树,返回树的根节点
     84 int build_tree(struct node arr[], int cnt)
     85 {
     86     while (1) {
     87         int i;
     88         int min1 = -1;              //权值最小的节点编号
     89         int min2 = -1;              //权值第二小的节点编号
     90         int root_node = 0;          //根节点(没有父节点)的个数
     91 
     92         for (i = 0; i < cnt; ++i) {
     93             if (arr[i].parent>= 0)    //拥有父节点,则跳过这个结点
     94                 continue;
     95             ++root_node;        //根节点加1
     96             if (min1 < 0) {
     97                 min1 = i;
     98             } else if (arr[i].val < arr[min1].val) {    //出现比第一更小的,更新
     99                 min2 = min1;
    100                 min1 = i;
    101             } else if (min2 < 0) {
    102                 min2 = i;
    103             } else if (arr[i].val < arr[min2].val) {    //当前节点权值比第二小节点更小
    104                 min2 = i;
    105             }
    106         }
    107         if (root_node < 2)
    108             break;
    109         arr[cnt].left = min2;
    110         arr[cnt].right = min1;
    111         arr[cnt].val = arr[min1].val + arr[min2].val;
    112         arr[cnt].parent = -1;
    113         arr[min1].parent = cnt;
    114         arr[min2].parent = cnt;
    115         ++cnt;
    116     }
    117     return cnt;
    118 }
  • 相关阅读:
    《Scrum实战》第4次课【全职的Scrum Master】作业汇总
    回顾Scrum学习:《Scrum实战》第4次课【全职的Scrum Master】作业
    孙式无极桩站桩要领--林泰年
    [Android Tips] 29. 如何判断当前编译的是哪个 Flavor ?
    [Jenkins] 解决 Gradle 编译包含 SVG Drawable 出现异常
    [Android Tips] 28. 如何指定运行特定的 Android Instrumentation Test
    [Gradle] 给已存在的 task 添加依赖
    [Gradle] 针对不同的项目类型应用不同的 findbugs 配置
    [Android Tips] 27. 检查 APK 是否可调试
    [Gradle] 如何强制 Gradle 重新下载项目的依赖库
  • 原文地址:https://www.cnblogs.com/tenjl-exv/p/12883499.html
Copyright © 2020-2023  润新知