二进制树中距离为k的节点

时间:2011-10-23 08:02:17

标签: algorithm data-structures

您将获得一个函数printKDistanceNodes,它接收二叉树的根节点,一个起始节点和一个整数K.完成该函数以打印所有节点的值(每行一个),这是K的值距离给定起始节点的排序顺序。距离可以向上或向下。

7 个答案:

答案 0 :(得分:3)

private void printNodeAtN(Node root, Node start, int k) {
    if (root != null) {
        // calculate if the start is in left or right subtree - if start is
        // root this variable is null
        Boolean left = isLeft(root, start);
        int depth = depth(root, start, 0);

        if (depth == -1)
            return;
        printNodeDown(root, k);

        if (root == start)
            return;

        if (left) {
            if (depth > k) {
                // print the nodes at depth-k level in left tree
                printNode(depth - k - 1, root.left);
            } else if (depth < k) {
                // print the nodes at right tree level k-depth
                printNode(k - depth - 1, root.right);
            } else {
                System.out.println(root.data);
            }
        } else {
            // similar if the start is in right subtree
            if (depth > k) {
                // print the nodes at depth-k level in left tree
                printNode(depth - k - 1, root.right);
            } else if (depth < k) {
                // print the nodes at right tree level k-depth
                printNode(k - depth - 1, root.left);
            } else {
                System.out.println(root.data);
            }
        }
    }
}

    // print the nodes at depth - "level" from root
void printNode(int level, Node root) {
    if (level == 0 && root != null) {
        System.out.println(root.data);
    } else {
        printNode(level - 1, root.left);
        printNode(level - 1, root.right);
    }

}

// print the children of the start
void printNodeDown(Node start, int k) {
    if (start != null) {
        if (k == 0) {
            System.out.println(start.data);
        }
        printNodeDown(start.left, k - 1);
        printNodeDown(start.right, k - 1);
    }
}

private int depth(Node root, Node node, int d) {
    if (root == null)
        return -1;
    if (root != null && node == root) {
        return d;
    } else {
        int left = depth(root.left, node, d + 1);
        int right = depth(root.right, node, d + 1);
        if (left > right)
            return left;
        else
            return right;
    }
}

答案 1 :(得分:1)

在距离K处最多有一个节点向上 - 从起始节点开始向上移动并沿着父节点向上移动K步。将其添加到已排序的数据结构中。

然后你需要添加向下的节点。为此,您可以使用队列执行BFS,在将队列插入队列时将深度与节点一起存储(起始节点位于0级,其子级位于1级,依此类推)。然后当您弹出节点时,如果它们处于级别K,则将它们添加到已排序的数据结构中。当您开始在K + 1级别弹出节点时,您可以停止。

最后从排序的数据结构中打印节点(它们将被排序)。

编辑:如果没有父指针:

写一个递归函数int Go(Node node),它返回相对于传入节点的起始节点的深度,如果节点的子树不包含start,则返回-1。该函数将找到第K个父项作为副作用。伪代码:

static Node KthParent = null;
static Node start = ...;
static int K = ...;

int Go(Node node) {
    if (node == start) return 0;

    intDepth = -1;

    if(node.LeftChild != null) {
        int leftDepth = Go(node.LeftChild);
        if(leftDepth >= 0) intDepth = leftDepth+1;
    }
    if (intDepth < 0 && node.rightChild != null) {
        int rightDepth = Go(node.RightChild);
        if(rightDepth >= 0) intDepth = rightDepth+1;
    }

    if(intDepth == K) KthParent = node;

    return intDepth;
}

答案 2 :(得分:0)

private static int printNodeAtK(Node root, Node start, int k, boolean found){
        if(root != null){
            if(k == 0 && found){
                System.out.println(root.data);
            }
            if(root==start || found == true){
                int leftd = printNodeAtK(root.left, start, k-1, true);
                int rightd = printNodeAtK(root.right,start,k-1,true);
                return 1;
            }else{
                int leftd = printNodeAtK(root.left, start, k, false);
                int rightd = printNodeAtK(root.right,start,k,false);
                if(leftd == k || rightd == k){
                    System.out.println(root.data);
                }
                if(leftd != -1 && leftd > rightd){
                    return leftd+1;
                }else if(rightd != -1 && rightd>leftd){
                    return rightd+1;
                }else{
                    return -1;
                }
            }

        }
        return -1;
    }

答案 3 :(得分:0)

typedef struct node
{
    int data;
    struct node *left;
    struct node *right;

}node;

void printkdistanceNodeDown(node *n, int k)
{
     if(!n)
       return ;

     if(k==0)
     {
        printf("%d\n",n->data);
        return;
     }

     printkdistanceNodeDown(n->left,k-1);
     printkdistanceNodeDown(n->right,k-1);   
}

void  printkdistanceNodeDown_fromUp(node* target ,int *k)
{   
    if(!target)
      return ;

      if(*k==0)
      {
         printf("%d\n",target->data); 
         return;
      }  
      else
      {
          int val=*k;
          printkdistanceNodeDown(target,val-1);
      }   
}

int printkdistanceNodeUp(node* root, node* n , int k)
{
    if(!root)
      return 0;

    if(root->data==n->data)
      return 1;

    int pl=printkdistanceNodeUp(root->left,n,k);      
    int pr=printkdistanceNodeUp(root->right,n,k);

     if(pl )
     {
      k--;

       if(k==0)
        printf("%d\n",root->data);
       else
      {
        printkdistanceNodeDown_fromUp(root->right,k);
        printkdistanceNodeDown_fromUp(root->left,k-1);
      }
       return 1;
    }

    if(pr )
    {
       k--;
      if(k==0)
        printf("%d\n",root->data);
      else
        { 
         printkdistanceNodeDown_fromUp(root->left,k);
         printkdistanceNodeDown_fromUp(root->right,k-1);
        }

       return 1;
    }

     return 0;
}

void printkdistanceNode(node* root, node* n , int k )
{
    if(!root)
      return ;

     int val=k;
     printkdistanceNodeUp(root,n,k);
     printkdistanceNodeDown(n,val);     

}

来电者功能:printkdistanceNode(root,n,k);

输出将打印距给定节点向上和向下距离k的所有节点。

答案 4 :(得分:0)

struct node{
       int data;
       node* left;
       node* right;
       bool printed;
};

void print_k_dist(node** root,node** p,int k,int kmax);
void reinit_printed(node **root);


void print_k_dist(node** root,node **p,int k,int kmax)
{
     if(*p==NULL) return;
     node* par=parent(root,p);
     if(k<=kmax &&(*p)->printed==0)
     {
             cout<<(*p)->data<<" ";
             (*p)->printed=1;
             k++;
             print_k_dist(root,&par,k,kmax);
             print_k_dist(root,&(*p)->left,k,kmax);
             print_k_dist(root,&(*p)->right,k,kmax);
     }
     else
         return;
}



void reinit_printed(node **root)
{
     if(*root==NULL) return;
     else
     {
         (*root)->printed=0;
         reinit_printed(&(*root)->left);
         reinit_printed(&(*root)->right);
     }
}          

答案 5 :(得分:0)

此处的代码PrintNodesAtKDistance将首先尝试查找所需的节点。

if(root.value == requiredNode)

当我们找到所需的节点时,我们将打印距此节点距离为K的所有子节点。

现在我们的任务是打印其他分支中的所有节点(上行和打印)。我们返回-1直到找不到我们想要的节点。当我们得到所需的节点时,我们得到lPathrPath >=0。现在我们必须打印距离为(lPath/rPath) -1

的所有节点
public void PrintNodes(Node Root, int requiredNode, int iDistance)

    {
        PrintNodesAtKDistance(Root, requiredNode, iDistance);
    }

    public int PrintNodesAtKDistance(Node root, int requiredNode, int iDistance)
    {
        if ((root == null) || (iDistance < 0))
            return -1;

        int lPath = -1, rPath = -1;

        if(root.value == requiredNode)
        {
            PrintChildNodes(root, iDistance);
            return iDistance - 1;
        }

        lPath = PrintNodesAtKDistance(root.left, requiredNode, iDistance);
        rPath = PrintNodesAtKDistance(root.right, requiredNode, iDistance);

        if (lPath > 0)
        {
            PrintChildNodes(root.right, lPath - 1);
            return lPath - 1;
        }
        else if(lPath == 0)
        {
            Debug.WriteLine(root.value);
        }

        if(rPath > 0)
        {
            PrintChildNodes(root.left, rPath - 1);
            return rPath - 1;
        }
        else if (rPath == 0)
        {
            Debug.WriteLine(root.value);
        }

        return -1;
    }

    public void PrintChildNodes(Node aNode, int iDistance)
    {
        if (aNode == null)
            return;

        if(iDistance == 0)
        {
            Debug.WriteLine(aNode.value);
        }

        PrintChildNodes(aNode.left, iDistance - 1);
        PrintChildNodes(aNode.right, iDistance - 1);
    }

答案 6 :(得分:0)

这是完整的java程序。灵感来自geeksforgeeks Algorith

// Java program to print all nodes at a distance k from given node

class BinaryTreePrintKDistance {
 Node root;

    /*
     * Recursive function to print all the nodes at distance k in tree (or
     * subtree) rooted with given root.
     */

    void printKDistanceForDescendant(Node targetNode, int currentDist,
            int inputDist) {
        // Base Case
        if (targetNode == null || currentDist > inputDist)
            return;

        // If we reach a k distant node, print it
        if (currentDist == inputDist) {
            System.out.print(targetNode.data);
            System.out.println("");
            return;
        }

        ++currentDist;
        // Recur for left and right subtrees
        printKDistanceForDescendant(targetNode.left, currentDist, inputDist);
        printKDistanceForDescendant(targetNode.right, currentDist, inputDist);
    }

    public int printkdistance(Node targetNode, Node currentNode,
            int inputDist) {

        if (currentNode == null) {
            return -1;
        }

        if (targetNode.data == currentNode.data) {
            printKDistanceForDescendant(currentNode, 0, inputDist);
            return 0;
        }

        int ld = printkdistance(targetNode, currentNode.left, inputDist);

        if (ld != -1) {

            if (ld + 1 == inputDist) {
                System.out.println(currentNode.data);

            } else {
                printKDistanceForDescendant(currentNode.right, 0, inputDist
                        - ld - 2);
            }

            return ld + 1;
        }

        int rd = printkdistance(targetNode, currentNode.right, inputDist);

        if (rd != -1) {

            if (rd + 1 == inputDist) {
                System.out.println(currentNode.data);

            } else {
                printKDistanceForDescendant(currentNode.left, 0, inputDist - rd
                        - 2);
            }

            return rd + 1;
        }

        return -1;

    }

    // Driver program to test the above functions
    @SuppressWarnings("unchecked")
    public static void main(String args[]) {
        BinaryTreePrintKDistance tree = new BinaryTreePrintKDistance();

        /* Let us construct the tree shown in above diagram */
        tree.root = new Node(20);
        tree.root.left = new Node(8);
        tree.root.right = new Node(22);
        tree.root.left.left = new Node(4);
        tree.root.left.right = new Node(12);
        tree.root.left.right.left = new Node(10);
        tree.root.left.right.right = new Node(14);
        Node target = tree.root.left;

        tree.printkdistance(target, tree.root, 2);
    }

    static class Node<T> {
        public Node left;
        public Node right;
        public T data;

        Node(T data) {
            this.data = data;
        }
    }

}