Tree 如何获取n元树中节点的路径?

Tree 如何获取n元树中节点的路径?,tree,lisp,Tree,Lisp,我在GNULisp中工作,希望获得某个节点的路径。 我已经设法解决了二叉树的问题,但是如果树是n元的,就找不到正确的递归规则。表示树(根(子树1)(子树2)…)。 那么,如何使用GNU Lisp获取n元树中节点的路径呢 二进制代码: ;checks if element e is in l (defun partof(l e) (cond ((null l) nil) ((equal l e) T) ((atom l) nil)

我在GNULisp中工作,希望获得某个节点的路径。 我已经设法解决了二叉树的问题,但是如果树是n元的,就找不到正确的递归规则。表示树(根(子树1)(子树2)…)。 那么,如何使用GNU Lisp获取n元树中节点的路径呢

二进制代码:

;checks if element e is in l
(defun partof(l e)
    (cond
        ((null l) nil)
        ((equal l e) T)
        ((atom l) nil)
        (T (find T (mapcar (lambda (l) (partof l e)) l)))))

;get the path   
(defun path(l e)
    (cond
        ((null l) nil)
        ((equal (car l) e) (list (car l))) ;if the element is the root of subtree return it
        ((partof (cadr l) e) (cons (car l) (path (cadr l) e))) ;if it is in the first subtree, get the root and check in first subtree until you get to it
        ((partof (caddr l) e) (cons (car l) (path(caddr l) e))) ; get the root and parse the second subtree
        (T nil))) ;here i can't find the rule to check in the rest of the subtrees
我还对一种全新的方式感兴趣,不仅仅是完成这一种。 n元树是这样的:(根(子树1)(子树2)(子树3)…),例如(A(B(C)(D))(E(F)(G))(H(I)(J))是一棵完整的树

                   A
               /   |   \
              B    E    H
             /\    /\   /\
            C D   F G  I J

记住我学到的关于配方和“相信递归”的知识,我可以提供以下内容:

CL-USER> (defun path (tree elt)
           (labels ((find-path (tree elt path)
                      (cond ((null tree) nil)
                            ((equal (car tree) elt) (cons elt path))
                            (t (some #'(lambda (sub)
                                         (find-path sub elt (cons (car tree) path)))
                                     (cdr tree))))))
             (reverse (find-path tree elt '()))))
STYLE-WARNING: redefining COMMON-LISP-USER::PATH in DEFUN(A (B (C) (D)) (E (F) (G)) (H (I) (J)))
PATH
CL-USER> (path '(A (B (C) (D)) (E (F) (G)) (H (I) (J))) 'D)
(A B D)
请注意,我在这里一直在使用SBCL,但它至少应该给您一个想法…

从根到节点的路径(递归方法) GNU CLISP 2.49上的工作:

CL-USER> (defparameter *tree* '(a (b (c) (d)) (e (f) (g)) (h (i) (j))))
*TREE*
CL-USER> (find-path *tree* 'd)
(A B D)
从一个任意节点到另一个任意节点的路径 OP没有说他/她想要得到什么样的路径:从根到节点,或者在两个任意节点之间。所以这个函数解决了在树的两个任意节点之间寻找路径的更一般的任务

(defun find-path* (tree x y)
  (labels ((till-d (a b i)
             (if (and (eq (car a) (car b))
                      a
                      b)
                 (till-d (cdr a) (cdr b) (1+ i))
                 i)))
    (let* ((x-path (find-path tree x))
           (y-path (find-path tree y))
           (pos (till-d x-path y-path 0)))
      (append (reverse (nthcdr (1- pos) x-path))
              (nthcdr pos y-path)))))
工作原理如下:

CL-USER> (find-path* *tree* 'd 'c)
(D B C)
CL-USER> (find-path* *tree* 'd 'g)
(D B A E G)
CL-USER> (find-path* *tree* 'b 'h)
(B A H)
CL-USER> (find-path* *tree* 'd 'd)
(D)
现在,许多任务也可以很容易地解决(节点之间的距离等)。

这与查找二叉树节点的路径没有什么不同。我正在发布的二叉树有一个解决方案。。您可以对N路树实现相同的功能。 //您必须编写一个循环来调用all-the-child,而不是为left和right-child调用递归函数,您将得到它

包二叉树路径

导入java.util.ArrayList

/* *您将获得一个二叉树(根节点)。。并且给出了一个键,该键可能在树中,也可能不在树中。 您必须找到从根到节点的完整路径

范例

                A
           /           \
       B                C
         \               /
          D           E
        /    \           \
      K      L        M
    /
Z
您已经指定了节点Z(或节点的键)和节点A(根) 所以你的输出应该是

A B D K Z

如果给定M,则输出应为 A C E M

*/

公共类主类{ 公共静态void main(字符串参数[]){

//首先创建树
Node rootNode=新节点('A',新节点('B',null,
新节点('D',
新节点('K',
新节点('Z',空,
空),空),
新节点('L',null,null)),
新节点('C',
新节点('E',
无效的
新节点('M',null,null)),null));
ArrayList路径=新建ArrayList();
System.out.println(getPath(rootNode,'Z',path));
System.out.println(路径);
路径=新的ArrayList();
System.out.println(getPath(rootNode,'M',path));
System.out.println(路径);
}
静态布尔getPath(节点根节点、字符键、ArrayList路径){
//如果找到节点,则返回true
if(rootNode==null)
返回false;
if(rootNode.getVal()==键){
add(rootNode);
返回true;
}
布尔left\u check=getPath(rootNode.left,key,path);
布尔右键检查=getPath(rootNode.right,key,path);
如果(左检查| |右检查){
add(rootNode);
返回true;
}
返回false;
}
静态类节点{
char-val;
左淋巴结;
节点权;
公共节点(字符值、左节点、右节点){
这个。左=左;
这个。右=右;
这个.val=val;
}
公共字符getVal(){
返回val;
}
公共字符串toString(){
返回“+val+”;
}
}

}

“树被表示(根(子树1)(子树2)…)。你能澄清一下树的结构吗?你想返回什么作为路径吗?我举了一个树的例子。从根到节点的路径(传递到所需节点的所有节点).Path to D:A,B,D。你可能也对它感兴趣。@Mark,这篇文章是关于二叉树的。我为此编写了解决方案,我对n元树很感兴趣。谢谢。@CristiDeac Stack Overflow是一个面向专业和热心程序员的网站。对于类似问题的解决方案,大多数专业和热心程序员都会非常感激LeMS,因为专业和热情的程序员愿意考虑类似情况下的解决方案,它们如何能被修改为新的情况。马克并没有声称该职位将解决您的问题,只是它是相似的,可能是有用的或有趣的。堆栈溢出不是一个代码工厂;需要解决一些规范的代码。科学的问题不是获得有用结果的最佳方式伟大的解决方案!谢谢!
                A
           /           \
       B                C
         \               /
          D           E
        /    \           \
      K      L        M
    /
Z
    //first create tree
    Node rootNode = new Node ('A' , new Node('B',null,
                                             new Node('D',
                                                      new Node('K',
                                                               new Node('Z',null,
                                                               null),null),
                                                      new Node('L',null,null))),
                                    new Node('C',
                                             new Node('E',
                                                      null,
                                                      new Node('M',null,null)),null) );

    ArrayList <Node> path = new ArrayList<Node>();
    System.out.println(getPath(rootNode,'Z',path));
    System.out.println(path);
    path = new ArrayList<Node>();
    System.out.println(getPath(rootNode,'M',path));
    System.out.println(path);

}
static boolean getPath(Node rootNode, char key, ArrayList<Node> path ){
    //return true if the node is found
    if( rootNode==null)
        return false;
    if (rootNode.getVal()==key){
        path.add(rootNode);
        return true;
    }
    boolean left_check = getPath( rootNode.left,key,path);
    boolean right_check = getPath( rootNode.right,key,path);
    if ( left_check || right_check){
        path.add(rootNode);
        return true;
    }
    return false;

}
static class Node {
    char val;
    Node left;
    Node right;
    public Node( char val, Node left, Node right){
        this.left=left;
        this.right=right;
        this.val=val;
    }
    public char getVal(){
        return val;
    }
   public String toString(){
        return " " + val + " ";
    }
}