【问题标题】:Printing Binary Search Tree with numbered nodes打印带有编号节点的二叉搜索树
【发布时间】:2017-11-29 21:16:40
【问题描述】:

我想对 BST 进行 InOrder 遍历并打印节点。我可以很好地打印树,但我无法正确编号。

如果有人想编译并试一试,这里就是所有代码。谢谢!

#include <time.h>
#include <stdlib.h>
#include <stdio.h>



struct Node_h {
    int start_addr;
    int size;

    struct Node_h* left;
    struct Node_h* right;
};

struct Node_h* newHoleNode(int st, int size) {
    struct Node_h* tmp = (struct Node_h*)malloc(sizeof(struct Node_h));
    tmp->start_addr = st;
    tmp->size = size;
    tmp->left = NULL;
    tmp->right = NULL;
    return tmp;
}

int compare(struct Node_h* lhs, struct Node_h* rhs) {
    if(lhs->size != rhs->size) 
        return (lhs->size < rhs->size) ? -1 : 1;
    else if(lhs->start_addr == rhs->start_addr)
        return 0;
    else
        return (lhs->start_addr < rhs->start_addr) ? -1 : 1;
}

struct Node_h* insertHole(struct Node_h* cur, struct Node_h* add) {
    /* If the tree is empty, return a new node */
    if (cur == NULL) 
        return add;

    /* Otherwise, recur down the tree */
    if (compare(add, cur) == -1) {
        cur->left  = insertHole(cur->left, add);
    }
    else if(compare(add, cur) == 1) {
        cur->right = insertHole(cur->right, add);
    }

    /* return the (unchanged) node pointer */
    return cur;
}

int printHoles(struct Node_h* cur, int num) {
    if(cur == NULL) {
        return 0;
    }
    int t = 1 + num;
    t += printHoles(cur->left, num);
    printf("Hole %d: start location = %d, size = %d\n", t, cur->start_addr, cur->size);
    t += printHoles(cur->right, t);
    return t;
}

int main(int argc, char const *argv[]) {
    srand(time(NULL));   // should only be called once
    int pid = 0;
    struct Node_h* root = NULL;
    for (int i = 0; i < 1000; ++i) {
        int size = rand() % 10000;
        root = insertHole(root, newHoleNode(pid++, size));
    }
    printHoles(root, 0);
    return 0;
}

编号总是大量随机 +/- 数字或类似的数字。救命!

孔 1:起始位置 = 168,大小 = 12

孔 2:起始位置 = 665,大小 = 12

第 4 洞:开始位置 = 506,大小 = 14

第 5 洞:起始位置 = 908,尺寸 = 30

第 11 洞:起始位置 = 498,尺寸 = 31

第 13 洞:开始位置 = 340,大小 = 38

第 14 洞:起始位置 = 378,大小 = 44

第 29 洞:起始位置 = 303,尺寸 = 54

第 30 洞:开始位置 = 948,大小 = 58

孔 60:起始位置 = 503,尺寸 = 70

【问题讨论】:

  • 节点编号是什么意思?
  • 它们应该被打印出来:“Hole 1 ....\nHole 2....\nHole 3....”等等。当然是升序。
  • @D.Lamkin 当您想要编号时,您的意思是按递增顺序(对于 BST 用于对节点进行排序的任何内容)?那么按照遍历顺序编号呢?
  • 是的,它基本上只是一个行号。
  • @D.Lamkin 仅供参考,您可以使用以下模式,这样您就不必在任何地方输入struct Node_htypedef struct Node_h { ... } Node;

标签: c data-structures binary-search-tree


【解决方案1】:

num 设为指针,并在访问节点后直接递增。通过如下修改,printHoles 不再需要返回int

void printHoles(struct Node_h* cur, int* num) {
  if (cur == NULL) {
    return;
  }
  printHoles(cur->left, num);
  printf("Hole %d: start location = %d, size = %d\n", *num, cur->start_addr, cur->size);
  (*num)++;
  printHoles(cur->right, num);
}

【讨论】:

  • 这是另一种有效的方法,但不是有效的 c 代码
  • @Ctx 对。我忘了是C。
【解决方案2】:
// num is the number of nodes printed so far
// return the number of nodes printed so far
int printHoles(struct Node_h* cur, int num) {
    if(NULL == cur) {
        // last printed not changed
        return num;
    }
    num = printHoles(cur->left, num);
    printf("%d. size = %d\n", num + 1, cur->size);
    num = printHoles(cur->right, num + 1);
    return num;
}

我们可以使用num 来跟踪到目前为止打印的节点数。如果不使用t,这应该更清晰正确。

【讨论】:

    【解决方案3】:

    如果你像这样重写你的函数

    int printHoles(struct Node_h* cur, int num) {
        if(cur == NULL) {
            return num;
        }
        num = printHoles(cur->left, num) + 1;
        printf("Hole %d: start location = %d, size = %d\n", num, cur->start_addr, cur->size);
        num = printHoles(cur->right, num);
        return num;
    }
    

    它应该正确跟踪输出值的数量。在每次printf()-call 之前,num 现在加一并且每次递归调用都返回,到那时为止输出了多少个值。这应该符合您的预期。

    【讨论】:

    • 我不认为这个答案是正确的,因为如果我在节点 N {size=3, left=NULL, right=Node(5)}, and num=4, 那么我打印9. size=3. 。这似乎不对。
    • 对于任何重要的 BST 来说,这绝对是不正确的。
    • @BlackSheep 好吧,你刚刚复制了我的答案,发现我的错误是“+=”而不是“=”,恭喜;)
    • 我实际上是在独立解决这个问题,并在将其用于我的测试输入后提出了该解决方案。但你认为我抄袭了你,这很好
    • @BlackSheep 哦,好吧,抱歉,我肯定误解了巧合;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多