Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 排序谓词使节点按深度优先搜索顺序排序_Algorithm_Sorting_Tree_Predicate_Depth First Search - Fatal编程技术网

Algorithm 排序谓词使节点按深度优先搜索顺序排序

Algorithm 排序谓词使节点按深度优先搜索顺序排序,algorithm,sorting,tree,predicate,depth-first-search,Algorithm,Sorting,Tree,Predicate,Depth First Search,我有一个节点列表,其中每个节点都属于一个或多个树。(他们不一定有共同的祖先) 我想按照深度优先搜索时查找节点的相同顺序对节点进行排序 假设我有一个谓词用于将树根排序在一起,另一个谓词用于将公共父级的子级排序在一起。每个节点都有一个父访问器和一个子枚举器。出于性能原因,我希望避免使用Children枚举(如果可能的话) 谓词传递给排序函数的伪代码是什么(如果节点1小于节点2,谓词将返回布尔值)。我认为,您需要在节点中存储有用的信息,以便谓词可以从一对未连接的节点中选择前一个节点 以下是我的尝试(可

我有一个节点列表,其中每个节点都属于一个或多个树。(他们不一定有共同的祖先)

我想按照深度优先搜索时查找节点的相同顺序对节点进行排序

假设我有一个谓词用于将树根排序在一起,另一个谓词用于将公共父级的子级排序在一起。每个节点都有一个父访问器和一个子枚举器。出于性能原因,我希望避免使用Children枚举(如果可能的话)


谓词传递给排序函数的伪代码是什么(如果节点1小于节点2,谓词将返回布尔值)。

我认为,您需要在节点中存储有用的信息,以便谓词可以从一对未连接的节点中选择前一个节点

以下是我的尝试(可能不是很聪明,甚至不是很有效):

import java.util.ArrayList;
导入java.util.Collections;
导入java.util.List;
/**
*
*/
公共类排序树{
私有静态类节点实现可比较的{
私有最终字符串数据;
专用节点p,l,r;
私有整数序数=0;
公共节点(字符串数据){
这个数据=数据;
}
公共节点setLeft(节点n){
n、 序数=序数+1;
if(序数==0)
n、 序数=2;
其他的
n、 序数=序数+2;
n、 p=这个;
返回n;
}
公共节点设置权限(节点n){
if(序数==0)
n、 序数=1;
其他的
n、 序数=序数+4;
n、 p=这个;
返回n;
}
公共字符串toString(){
返回数据;
}
公共整数比较(节点o){
//检查其中一个参数是否为root
if(p==null&&o.p!=null)返回-1;
如果(p!=null&&o.p==null)返回1;
if(p==null&&o.p==null)返回0;
//检查其中一个参数是否为左子树,而另一个参数是否为右子树
if(序号%2==0&&o.ordinal%2==1)返回-1;
if(序号%2==1&&o.ordinal%2==0)返回1;
//如果序数相同,则第一个元素是父元素序数较大的元素
if(序数==o.ordinal){
返回o.p.ordinal-p.ordinal;
}
返回序号-o.序号;
}
}
公共静态void main(字符串[]args){
列表节点=新的ArrayList();
节点根=新节点(“根”);节点。添加(根);
Node left=root.setLeft(新节点(“A”);nodes.add(左);
Node leftLeft=left.setLeft(新节点(“C”);nodes.add(leftLeft);nodes.add(leftLeft.setLeft(新节点(“D”));
nodes.add(left.setRight(新节点(“E”)));
Node right=root.setRight(新节点(“B”);nodes.add(右);
nodes.add(right.setLeft(新节点(“F”));nodes.add(right.setRight(新节点(“G”));
集合。排序(节点);
System.out.println(节点);
}
}

我找到了一个简单可行的解决方案:

对于节点,有一个从根返回路径的函数。例如,在文件系统中,文件的路径可以是:c:\directory\file.txt,其中“c:”、“directory”和“file.txt”是父节点

谓词只需要将路径一起比较,就像简单的字符串比较一样。路径不需要是字符串,路径比较函数需要从根开始逐个比较路径元素,并在路径元素不同时返回


结果排序与深度优先搜索相同。

您想按级别顺序排序吗?无论您提出什么,排序(在
O(n logn)
中)总是比枚举(在
O(n)
中)慢。埃尔米:我不明白您的问题,我无法在我的节点中存储信息。它们是只读的,仅仅为了对它们进行排序而修改它们的结构是没有意义的。可能需要的数据比我的代码中显示的要少,但我确信需要一些数据。是的,这是相同的,但复杂性是
O(n*logn*d)
,其中
d
是平均树深度(因为比较路径需要时间!)。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 *
 */
public class SortingTree {

    private static class Node implements Comparable<Node> {
        private final String data;
        private Node p, l, r;

        private int ordinal = 0;

        public Node(String data) {
            this.data = data;
        }

        public Node setLeft(Node n) {
            n.ordinal = ordinal + 1;
            if (ordinal == 0)
                n.ordinal = 2;
            else
                n.ordinal = ordinal + 2;
            n.p = this;
            return n;
        }

        public Node setRight(Node n) {
            if (ordinal == 0)
                n.ordinal = 1;
            else
                n.ordinal = ordinal + 4;
            n.p = this;
            return n;
        }

        public String toString() {
            return data;
        }


        public int compareTo(Node o) {
            // check if one of args is root
            if (p == null && o.p != null) return -1;
            if (p != null && o.p == null) return 1;
            if (p == null && o.p == null) return 0;

            // check if one of args is left subtree, while other is right
            if (ordinal % 2 == 0 && o.ordinal % 2 == 1) return -1;
            if (ordinal % 2 == 1 && o.ordinal % 2 == 0) return 1;

            // if ordinals are the same, first element is the one which parent have bigger ordinal
            if (ordinal == o.ordinal) {
                return o.p.ordinal - p.ordinal;
            }
            return ordinal - o.ordinal;
        }
    }

    public static void main(String[] args) {
        List<Node> nodes = new ArrayList<Node>();

        Node root = new Node("root"); nodes.add(root);
        Node left = root.setLeft(new Node("A")); nodes.add(left);
        Node leftLeft = left.setLeft(new Node("C")); nodes.add(leftLeft); nodes.add(leftLeft.setLeft(new Node("D")));
        nodes.add(left.setRight(new Node("E")));

        Node right = root.setRight(new Node("B")); nodes.add(right);
        nodes.add(right.setLeft(new Node("F"))); nodes.add(right.setRight(new Node("G")));

        Collections.sort(nodes);
        System.out.println(nodes);
    }
}