предикат сортировки для сортировки узлов в порядке поиска в глубину - PullRequest
0 голосов
/ 26 января 2011

У меня есть список узлов, где каждый из узлов принадлежит одному или нескольким деревьям.(они не обязательно имеют общего предка)

Я хочу отсортировать узлы в том же порядке, в котором я их нашел бы при выполнении поиска в глубину.

Допустим, у меня есть предикатсортировка корней деревьев вместе, и другой предикат для сортировки потомков общего родителя.Каждый узел имеет родительский метод доступа и дочерний перечислитель.Я хочу избежать использования перечисления Children по соображениям производительности (если это возможно).

Каким может быть псевдокод для предиката для передачи в функцию сортировки (предикат будет возвращать логическое значение, если узел 1 меньшечем узел 2).

Ответы [ 2 ]

0 голосов
/ 27 января 2011

Я нашел простое рабочее решение:

Для узла есть функция, которая возвращает путь от корня. Например, в файловой системе путь к файлу может быть следующим: c: \ directory \ file.txt, где «C:», «directory» и «file.txt» являются родительскими узлами.

Предикат просто должен сравнивать пути вместе, как это делает простое сравнение строк. Путь не должен быть строкой, функция сравнения пути должна сравнивать элементы пути по одному, начиная с корня, и возвращать, как только элемент пути будет другим.

Результирующая сортировка аналогична поиску по глубине.

0 голосов
/ 26 января 2011

Я думаю, вам нужно хранить полезную информацию в узлах, поэтому предикат может выбрать предыдущий узел из пары несвязанных узлов.

Вот моя (может быть, не очень умная или даже работающая) попытка:

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