【问题标题】:Sort through list of nodes which have two dimensional properties对具有二维属性的节点列表进行排序
【发布时间】:2015-05-19 15:23:53
【问题描述】:

这是我的节点类

public class Node
{
    int Data= -1;
    int X;
    int Y;
    Node LeftChild = null;
    Node RightChild = null;
    Node(int i)
    {
        this.Data = i;
    }
}

这是我的中序遍历代码:

public static void inorder(Node current, int horiz_dist, int verti_dist)
{
    if(current == null)
        return;
    inorder(current.LeftChild, ++horiz_dist, ++verti_dist);
    horiz_dist--;
    verti_dist--;
    System.out.println("Node "+current.Data+": X = "+horiz_dist+", Y = "+verti_dist);
    current.X = horiz_dist;
    current.Y = verti_dist;
    node_list.add(current);
    inorder(current.RightChild, --horiz_dist, ++verti_dist);
    horiz_dist++;
    verti_dist--;
}

我有一个节点列表,这些节点是在中序遍历中迭代二叉树时得到的。以下是该遍历的输出:

节点 18:X = 3,Y = 3

节点 7:X = 2,Y = 2

节点 5:X = 1,Y = 1

节点 12:X = 1,Y = 3

节点 9:X = 0,Y = 2

节点 13:X = -1,Y = 3

节点 6:X = 0,Y = 0

节点 8:X = -1,Y = 1

节点 10:X = -2,Y = 2

节点 15:X = -3,Y = 3

我想先根据X(降序)然后Y(升序)对所有节点进行排序。其中XY 分别是与根节点的距离。所以最终输出将是:

节点 18:X = 3,Y = 3

节点 7:X = 2,Y = 2

节点 5:X = 1,Y = 1

节点 12:X = 1,Y = 3

节点 6:X = 0,Y = 0

节点 9:X = 0,Y = 2

节点 8:X = -1,Y = 1

节点 13:X = -1,Y = 3

节点 10:X = -2,Y = 2

节点 15:X = -3,Y = 3

编辑:这是我的比较器逻辑。我更新了它。现在成功了

This is comparator logic I wrote:

`Collections.sort(node_list, new Comparator(){

        public int compare(Node second, Node first)

        {

            if(first.X > second.X)
                return 1;
            else if(first.X < second.X)
                return -1;
            else if(first.X == second.X)
            {
                if(first.Y < second.Y)
                    return 1;
                else if(first.Y > second.Y)
                    return -1;
                else if( first.Y == second.Y)
                    return 0;
            }
            return 0;
        }
    });`

【问题讨论】:

  • 当我意识到我误解了这个问题时,我收回了我的答案。对于那个很抱歉!但是您可以使用 ArrayList::sort ,因为我认为您正在使用带有自定义比较器的 Java。这是您最简单的解决方案。但是,如果它就像一个家庭作业解决方案,因为您在这里滚动自己的 BST,那么这种遍历需要的是一个队列。您不能使用标准的前序/中序/后序遍历递归地执行此操作,因为我们需要一次遍历树一个“行”。这些递归算法总是挖掘到叶子而不是“行”处理。
  • 因此,如果您想在不依赖单独的排序算法的情况下执行此操作,则必须一次处理您的树,从左到右(或从右到左降序) X 顺序),从上到下。为此,您需要从右到左按“阶段”传递树的每一行,然后推送到队列中。或者,如果您使用两个队列,一个用于“当前行”,另一个用于“下一行”,则更容易。然后在当前队列为空时交换队列并重复直到两个队列都为空。

标签: performance algorithm sorting binary-tree nodes


【解决方案1】:

您可以将 std::sort 与自定义比较功能一起使用。

假设你有一个节点向量std::vector&lt;Node&gt; vec,那么你可以这样使用它

std::sort(vec.begin(), vec.end(), compare);

compare 定义如下

bool compare(Node a, Node b)
{
    if (a.X > a.X) return true;
    if (a.Y > a.Y) return true;
}

这个算法的运行时间是O(n*log(n))

【讨论】:

  • 你能展示 std::sort 的例子吗?我不熟悉方法。需要多少时间。通常对于二维比较,它将在 O(N^2) 时间内进行。我想知道它是否可以在 O(N*logN) 时间内完成。
【解决方案2】:

唷,让我们再试一次,因为我最初误解了这个问题。由于您的整个目标是通过树遍历过程分配这些 X/Y 值,首先是坏消息:

递归算法在这里不起作用。

无论您使用的是顺序遍历还是前序遍历或后序遍历,所有这些算法都会崩溃,因为它们希望以类似堆栈的 LIFO 方式递归地挖掘到叶子(递归使用像 LIFO 结构一样调用堆栈)。如果您想以先排序 Y 然后排序 X 的方式输出,它们会很好,但反过来不行。先做 X 相当棘手。

伪代码解决方案:

List<Node> current_row;
List<Node> next_row;

root_node.x = 0;
root_node.y = 0;
current_row.push(root_node);

// Right-to-Left, Top-to-Bottom
while (!current_row.empty())
{
    do
    {
        Node node = current_row.pop();
        // output node data

        if (node.right_child)
        {
            node.right_child.x = node.x + 1;
            node.right_child.y = node.y + 1;
            next_row.push(node.right_child);
        }

        if (node.left_child)
        {
            node.left_child.x = node.x - 1;
            node.left_child.y = node.y + 1;
            next_row.push(node.left_child);
        }
    } while (!current_row.empty());
    current_row.swap(next_row);
}

您也可以在此处使用单个队列,但我认为这种“基于行”的心态可能会帮助您初步了解正在发生的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2011-08-09
    • 2019-12-26
    • 1970-01-01
    相关资源
    最近更新 更多