在二叉树的每个节点中填充下一个右指针

时间:2016-01-13 05:59:13

标签: c tree queue tree-traversal

我想在C中做this problem on Leetcode

给出以下二叉树,

     1
   /  \
  2    3
 / \    \
4   5    7

调用函数后,树应该如下所示:

     1 -> NULL
   /  \
  2 -> 3 -> NULL
 / \    \
4-> 5 -> 7 -> NULL

我正在做的是为树的Level Order Traversal创建一个队列 并将每个节点的下一个指针连接到每个节点的下一个队列节点 水平。为了分离级别,我将NULL指针排入队列。

所以对于上面的例子::队列是 - > [1,#,2,3,#,4,5,7,#]其中#是NULL ptr。

这是我的问题代码::

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  struct TreeLinkNode *left, *right, *next;
 * };
 *
 */
bool isEmpty(int start,int end){
    if(start > end)
        return true;
    return false;
}

void connect(struct TreeLinkNode *root) {
    if(!root || (!root->left && !root->right))
        return;
    int cap = 1000;
    struct TreeLinkNode** q = malloc(cap* sizeof(struct TreeLinkNode*));
    int start=0, end=-1, curLevel=1, nextLevel=0;
    // enqueue
    q[++end] = root;
    while(isEmpty(start, end) == false){
        //dequeue
        struct TreeLinkNode* temp = q[start++];
        curLevel--;
        if(isEmpty(start, end) == false && curLevel !=0)
            temp->next = q[start];
        if(temp->left){
            q[++end] = temp->left;
            nextLevel++;
        }
        if(temp->right){
            q[++end] = temp->right;
            nextLevel++;
        }
        if(curLevel ==0){
            curLevel = nextLevel;
            nextLevel =0;
        }
        if(start> cap-50 || end> cap-50)
            q = realloc(q, 2*cap*sizeof(struct TreeLinkNode *));
    }
    free(q);
}

代码显然适用于小型测试用例,但对于Leetcode上较大的代码,代码会产生运行时错误。 我不知道我做错了什么。 请帮忙。如果有人可以在Leetcode

上运行此代码,我将非常感激

2 个答案:

答案 0 :(得分:0)

当您分析上一级别的最后一个节点时,会发生级别结束。由于每个级别在q中以NULL结尾,因此当temp为NULL时,表示已分析完整级别,您可以通过插入NULL来结束下一级别。

所以我对你的代码做了一些修改:

void connect(struct TreeLinkNode *root) {
    int cap = 1000;
    struct TreeLinkNode** q = malloc(cap* sizeof(struct TreeLinkNode*));
    int start=0, end=-1;
    // enqueue
    q[++end] = root;
    q[++end] = NULL; // End of first level
    for (;;) {
        //dequeue
        struct TreeLinkNode* temp = q[start++];
        if (temp == NULL) {
            if (q[start] == NULL) // Two consecutives NULL means end of tree
                break;
            q[++end] = NULL; // End of level
        } else {
            temp->next = q[start];
            if(temp->left)
                q[++end] = temp->left;
            if(temp->right)
                q[++end] = temp->right;
            if (end > cap-50) { // end is always greater or equal to start
                q = realloc(q, 2*cap*sizeof(struct TreeLinkNode *));
            }
        }
    }
    free(q);
}

我现在无法对它进行实际测试,因此可能无法直接使用,主要是为了这个想法。

答案 1 :(得分:0)

我将在 javascript 中提供我的结果,但我会提供有关以另一种语言重现此结果的步骤的足够说明:

  1. 使用 level order traversal (breadth-first search) 解决这个问题。
  2. 检查提供的根是否为空,如果是,我们立即返回
  3. 创建一个 queue,用于存储我们的二叉树节点
  4. 将根推入队列
  5. 启动一个只有当队列中有项目时才会运行的 while 循环
  6. 获取队列的长度并将其存储在变量中,例如queueLength
  7. 遍历队列的长度(queueLength),同时观察循环的当前索引;
  8. index 0 中移动/移除 queue 上的项目并将其保存为 currValue
  9. 首先检查它是否有左节点,如果有则将其推入队列
  10. 检查它是否也有节点值,如果有则将其推入队列
  11. 如果循环中的索引值不等于 queueLength-1,则 currValue.next 将等于 queue[0],即队列中的第一项。
  12. 如果循环中索引的值等于queueLength-1,那么这是这一层的最后一个节点,我们可以将它的下一个值设置为null
  13. while 循环会再次重复 step 6 - 12
const connect = function (root) {
    let queue = [];
    
    if(root){
        queue.push(root);
    }

    while (queue.length) {
        // let curr = queue.shift(1);
        const queueLength = queue.length;

        for (let i = 0; i < queueLength; i++) {
            const currValue = queue.shift(0);
            if (currValue.left) {
                queue.push(currValue.left);
            }

            if (currValue.right) {
                queue.push(currValue.right);
            }

            if (i !== queueLength - 1) {
                currValue.next = queue[0];
            }

            if (i === queueLength - 1) {
                currValue.next = null;
            }
        }
    }

    return root;
};