Java 如何垂直打印优先级队列

Java 如何垂直打印优先级队列,java,algorithm,Java,Algorithm,我想以树形格式打印队列。我实现了转换为数组,然后打印或使用迭代器遍历打印,但我希望输出的顺序如下 输入:钥匙1-10的优先级队列 树: 1 / \ 2 3 / \ / \ 4 5 6 7 / / \

我想以树形格式打印队列。我实现了转换为数组,然后打印或使用迭代器遍历打印,但我希望输出的顺序如下

输入:钥匙1-10的优先级队列

                      1
                   /     \
                 2         3
               /   \     /   \
              4     5   6     7
             /              /   \ 
            8              9     10
1
.2
..4
...8
..5
.3
..6
..7
...9
...10
输出

                      1
                   /     \
                 2         3
               /   \     /   \
              4     5   6     7
             /              /   \ 
            8              9     10
1
.2
..4
...8
..5
.3
..6
..7
...9
...10
因此,本质上我试图将输出表示为树格式。有没有内置的java方法可以帮我做到这一点


我试图通过为每个树级别创建新的数组来解决这些问题,但我意识到这并不是最优的,尤其是当队列的大小较大时

没有实际的方法为您格式化代码。最有可能的是,您必须找到自己的方式来格式化信息,或者使用for循环,或者类似的东西。Happy codin':)

没有实际的方法可以为您格式化代码。最有可能的是,您必须找到自己的方式来格式化信息,或者使用for循环,或者类似的东西。Happy codin':)

所需的输出格式称为
二叉树格式。要获得该输出,您必须将数字存储为二叉树(不一定是二叉搜索树),这需要
O(nlogn)
时间,然后您可以使用预顺序遍历轻松计算该顺序。整个程序的时间复杂度将是
O(nlogn)

所需的输出格式称为
二叉树的输出格式。要获得该输出,您必须将数字存储为二叉树(不一定是二叉搜索树),这需要
O(nlogn)
时间,然后您可以使用预顺序遍历轻松计算该顺序。整个程序的时间复杂度将是
O(nlogn)

我认为这种树的预序遍历递归是合适的

例如(在C/C++中),如果将
节点定义为

typedef struct node
{
    int data;
    node * left;
    node * right;
};

输出的递归函数可以(如C++标准流输出),如

void recursiveOut(节点*root,int级别=0)
//根-指向树(子树)顶部的指针
//级别-递归级别(等于.before值的数量)
{
//检查节点是否存在
如果(!root)
返回;
//当前节点的输出数据(即根)
对于(int i=0;i
它可以很容易地被称为如下

int main(void)
{
    node * root = NULL;
    // init the tree
    for (int i = 1; i <= 10; i++)
        add(root, i);   // I suppose you have some functions to make tree
    recursiveOut(root); // output the tree
    return 0;
}

我认为对于这种树的预序遍历,递归是合适的

例如(在C/C++中),如果将
节点定义为

typedef struct node
{
    int data;
    node * left;
    node * right;
};

输出的递归函数可以(如C++标准流输出),如

void recursiveOut(节点*root,int级别=0)
//根-指向树(子树)顶部的指针
//级别-递归级别(等于.before值的数量)
{
//检查节点是否存在
如果(!root)
返回;
//当前节点的输出数据(即根)
对于(int i=0;i
它可以很容易地被称为如下

int main(void)
{
    node * root = NULL;
    // init the tree
    for (int i = 1; i <= 10; i++)
        add(root, i);   // I suppose you have some functions to make tree
    recursiveOut(root); // output the tree
    return 0;
}

优先级队列最常见的实现是将其存储在一个简单的数组中,其中索引i处的项的子项位于索引2i+1和2i+2处(假设数组从0开始索引)。这不是唯一可能的优先级队列实现,但它简单、实用,并且在大多数情况下是最有效的,除非优先级队列非常大,或者您需要其他原语来加快速度(例如合并两个优先级队列)

但是,Java不需要标准库来使用此(或任何)算法,因此它不公开有关优先级队列的任何内部信息;实现者可以自由使用他们认为方便的任何算法和底层存储,并且不可能直接访问底层阵列(如果有),也不可能找到项的子项

因此,如果您需要执行一些需要访问优先级队列实现的操作,则需要实现您自己的优先级队列。此类实现的示例不胜枚举,简单的web搜索应该可以找到几个[注1]

P> >对比,C++标准库具有二进制堆基元(和)的显式实现,它是使用二进制堆基元在一个随机访问容器上的适配器,因此它提供对底层数组的直接访问。

这使得在C++中很容易地解决问题,如果在爪哇中实现二进制堆,那么您可以很容易地适应下面的代码片段来生成所需的输出。这是一个简单的递归遍历二进制堆中隐式树的深度遍历。

#include <iostream>
#include <queue>
#include <vector>

template<typename V, typename C = std::vector<V>, typename Comp = std::less<V>>
class PrintablePriorityQueue : public std::priority_queue<V, C, Comp> {

  public:
    /* A real implementation would have more constructors :) */
    PrintablePriorityQueue() {}

    std::ostream& print(std::ostream& out, size_t i = 0, size_t depth = 0) const;
};

/* I left out the operator<< overload, which just calls print. With that,
   print would be made protected.
 */

template<typename V, typename C, typename Comp>
std::ostream& PrintablePriorityQueue<V, C, Comp>::print(std::ostream& out, size_t i, size_t depth) const {
  if (i < this->size()) {
    for (size_t j = depth; j; --j) out << '.';
    out << this->c[i] << '\n'; /* c is the underlying container */
    print(out, 2*i + 1, depth + 1);
    print(out, 2*i + 2, depth + 1);
  }
  return out;
}
请注意,二进制堆总是从左到右填充,因此图表的形状与示例不同


笔记
  • 就个人而言,我建议你看一看,特别是如果你正在学习的课程是教科书,但是任何好的算法教科书都可能描述算法

  • 优先级队列最常见的实现是将其存储在一个简单的数组中,其中索引i处的项的子项位于索引2i+1和2i+2处(假设数组从0开始索引)。这不是唯一可能的优先级队列实现,但它简单、实用,并且在大多数情况下是最有效的,除非优先级队列非常大,或者您需要其他原语来加快速度(例如合并两个优先级队列)

    但是,Java不需要标准库来使用此(或任何)算法,因此它不公开有关优先级队列的任何内部信息