【问题标题】:Tree: Level order Traversal using queue树:使用队列的级别顺序遍历
【发布时间】:2016-02-15 23:05:04
【问题描述】:

我写了使用队列遍历树的代码,但是下面的dequeue函数会产生错误,head = p->next有什么问题吗? 我无法弄清楚为什么这部分是错误的。

void Levelorder(void) {
node *tmp, *p;


if (root == NULL) return;

tmp = root;
printf("The level order is :\n");

while (tmp != NULL) {

    printf("%d, ", tmp->data);
    if (tmp->left) {
        enqueue(tmp->left);
    }
    if (tmp->right) {
        enqueue(tmp->right);
    }
    tmp = dequeue();
}

return;
}

void enqueue(node *p) {
if (head == NULL) {
    head = p;
}
else {
    tail->next = p;
}
tail = p;
p->next = NULL;
tail->next = NULL;

return;
}

node* dequeue(void) {
node *p;
p = head;
head = p->next;


if (head == NULL) {
    tail == NULL;
}

return p;
}

【问题讨论】:

    标签: c tree


    【解决方案1】:

    你的while循环的条件是:

    while (tmp != NULL) {
    

    所以它只会在dequeue 在此处返回NULL 时终止:

        tmp = dequeue();
    

    但是在查看出队的实现时,这不可能发生:

    node* dequeue(void) {
        node *p;
        p = head;
    

    这里,p 被取消引用:

        head = p->next;
    
        if (head == NULL) {
            tail == NULL;
        }
    

    在这里,p 被返回:

        return p;
    }
    

    要返回 NULL 指针并离开您的 while 循环,p 必须在此处为 NULL。但是,NULL 指针之前会被 head = p->next; 取消引用,这将导致分段错误(根据 C 语言的 UB)。

    如果head 是 NULL 指针,您应该在 dequeue-function 的开头检查并在这种情况下返回 NULL:

    node* dequeue(void) {
        node *p;
        if (!head)
             return NULL;
    
    ...
    

    【讨论】:

    • 感谢您的支持。但仍然无法理解 'head =p ->next' 的顺从机智。 'head = p->next' 如何尊重包含 NULL 指针的 p?
    • @Ezerk 它不能,这就是程序在那个时候崩溃的原因。也许你很恼火,你根本没有输出;这是因为printf() 通常会在终端设备上对其输出进行行缓冲。
    • 感谢您的评论。
    猜你喜欢
    • 2020-08-20
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多