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

发布于 2024-10-14 12:35:51 字数 240 浏览 6 评论 0原文

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

我想按照在进行深度优先搜索时找到它们的相同顺序对节点进行排序。

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

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

I have a list of nodes, where each of the nodes belong to one or multiple trees. (they do not necessarily share a common ancestor)

I want to sort the nodes in the same order I would find them when doing a Depth First Search.

Let say I have a predicate for sorting tree roots together, and another predicate to sort children of a common parent together. Each node have a Parent accessor, and a children enumerator. I want to avoid using the Children enumeration for performance reasons (if possible).

What can be the pseudo code for a predicate to pass to a sort function (the predicate would return a boolean value if node 1 is less than node 2).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白云悠悠 2024-10-21 12:35:51

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

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

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);
    }
}

I think, you need to store helpful information in nodes, so predicate can choose preceding node from pair of unconnected nodes.

Here's my (may be not very clever or, even, working) attempt:

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);
    }
}
薆情海 2024-10-21 12:35:51

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

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

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

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

I found an easy working solution:

For a node, have a function that returns the path from the root. For example, in a file system, the path for a file could be : c:\directory\file.txt, where "C:", "directory" and "file.txt" are the parent nodes.

The predicate simply need to compare the paths together, as a simple string comparison would do. The path does not need to be a string, the path comparison function need to compare path elements one by one starting at the root, and return as soon a path element is different.

The resulting sort is the same as a Depth First Search.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文