原文:

给定一棵二叉树,垂直打印。 以下示例说明了垂直顺序遍历。

           1
        /    \ 
       2      3
      / \   /   \
     4   5  6   7
               /  \ 
              8   9 
the output of print this tree vertically will be:
4
2
1 5 6
3 8
7
9

我们已经在中讨论了o(n ^ 2)pg电子试玩链接的解决方案。 在这篇文章中,讨论了一种基于哈希映射的有效pg电子试玩链接的解决方案。 我们需要检查所有节点到根的水平距离。 如果两个节点的水平距离(hd)相同,则它们在同一垂直线上。 hd 的想法很简单。 根的 hd 为 0,将右边(连接到右子树的边)视为 1 水平距离,而左边则视为 -1 水平距离。 例如,在上面的树中,节点 4 的 hd 为 -2,节点 2 的 hd 为 -1,节点 5 和 6 的 hd 为 0,节点 7 的 hd 为 2。

我们可以对给定的二叉树进行遍历。 在遍历树时,我们可以递归计算 hd。 最初,我们将根的水平距离设为 0。 对于左子树,我们将“水平距离”作为根的水平距离减去 1。对于右子树,我们将“水平距离”作为根的水平距离加上 1。对于每个 hd 值,我们在哈希映射中维护节点列表。 每当我们看到遍历中的节点时,我们都会进入哈希映射条目,并使用 hd 作为映射中的键将节点添加到哈希映射中。

以下是上述方法的 c 实现。 感谢 chirag 提供以下 c 实现。

c

// c   program for printing vertical order of a given binary tree
#include 
#include 
#include 

java

// java program for printing vertical order of a given binary tree
import java.util.treemap;
import java.util.vector;
import java.util.map.entry;
public class verticalorderbtree 
{
    // tree node
    static class node
    {
        int key;
        node left;
        node right;
        // constructor
        node(int data)
        {
            key = data;
            left = null;
            right = null;
        }
    }
    // utility function to store vertical order in map 'm'
    // 'hd' is horizontal distance of current node from root.
    // 'hd' is initially passed as 0
    static void getverticalorder(node root, int hd,
                                treemap> m)
    {
        // base case
        if(root == null)
            return;
        //get the vector list at 'hd'
        vector get =  m.get(hd);
        // store current node in map 'm'
        if(get == null)
        {
            get = new vector<>();
            get.add(root.key);
        }
        else
            get.add(root.key);
        m.put(hd, get);
        // store nodes in left subtree
        getverticalorder(root.left, hd-1, m);
        // store nodes in right subtree
        getverticalorder(root.right, hd 1, m);
    }
    // the main function to print vertical order of a binary tree
    // with the given root
    static void printverticalorder(node root)
    {
        // create a map and store vertical order in map using
        // function getverticalorder()
        treemap> m = new treemap<>();
        int hd =0;
        getverticalorder(root,hd,m);
        // traverse the map and print nodes at every horigontal
        // distance (hd)
        for (entry> entry : m.entryset())
        {
            system.out.println(entry.getvalue());
        }
    }
    // driver program to test above functions
    public static void main(string[] args) {
        // to do auto-generated method stub
        node root = new node(1);
        root.left = new node(2);
        root.right = new node(3);
        root.left.left = new node(4);
        root.left.right = new node(5);
        root.right.left = new node(6);
        root.right.right = new node(7);
        root.right.left.right = new node(8);
        root.right.right.right = new node(9);
        system.out.println("vertical order traversal is");
        printverticalorder(root);
    }
}
// this code is contributed by sumit ghosh

python

# python program for printing vertical order of a given
# binary tree
# a binary tree node
class node:
    # constructor to create a new node
    def __init__(self, key):
        self.key = key
        self.left = none
        self.right = none
# utility function to store vertical order in map 'm' 
# 'hd' is horizontal distance of current node from root
# 'hd' is initially passed as 0
def getverticalorder(root, hd, m):
    # base case
    if root is none:
        return
    # store current node in map 'm'
    try:
        m[hd].append(root.key)
    except:
        m[hd] = [root.key]
    # store nodes in left subtree
    getverticalorder(root.left, hd-1, m)
    # store nodes in right subtree
    getverticalorder(root.right, hd 1, m)
# the main function to print vertical order of a binary
#tree ith given root
def printverticalorder(root):
    # create a map and store vertical order in map using
    # function getverticalorder()
    m = dict()
    hd = 0
    getverticalorder(root, hd, m)
    # traverse the map and print nodes at every horizontal
    # distance (hd)
    for index, value in enumerate(sorted(m)):
        for i in m[value]:
            print i,
        print
# driver program to test above function
root = node(1)
root.left = node(2)
root.right = node(3)
root.left.left = node(4)
root.left.right = node(5)
root.right.left = node(6)
root.right.right = node(7)
root.right.left.right = node(8)
root.right.right.right = node(9)
print "vertical order traversal is"
printverticalorder(root)
# this code is contributed by nikhil kumar singh(nickzuck_007)

输出:

vertical order traversal is
4
2
1 5 6
3 8
7
9

基于哈希的pg电子试玩链接的解决方案的时间复杂度在我们具有良好的哈希函数(允许在o(1)时间内进行插入和检索操作)的假设下可以视为o(n)。 在上述 c 实现中,使用了 stl 的。 stl 中的映射通常是使用自平衡二分搜索树实现的,其中所有操作都需要o(logn)时间。 因此,上述实现的时间复杂度为o(nlogn)

请注意,上述pg电子试玩链接的解决方案可能以与树中出现的节点相同的垂直顺序打印节点。 例如,上述程序在 12 之前打印 12。

             1
          /     
         2       3
        /      /  
       4    5  6    7
                  /  
                 8 10  9 
                     11
                        12      

请参阅以下帖子,以了解基于层次顺序遍历的pg电子试玩链接的解决方案。 下面的帖子确保垂直线节点的打印顺序与树中出现的顺序相同。

另一种使用computeifabsent的方法

通过使用 java 中的computeifabsent方法和 java 中的映射,以及使用基于键自然排序的树映射,我们可以更简洁地用编写代码。

下面是上述方法的实现。

java

// java program for above approach
import java.util.arraylist;
import java.util.list;
import java.util.map;
import java.util.treemap;
public class binarytree 
{
  node root;
  // values class
  class values
  { 
    int max, min; 
  }
  // program to find vertical order
  public void verticalorder(node node) 
  {
    values val = new values();
    // create treemap
    map> map = new treemap>();
    // function call to findhorizonataldistance
    findhorizonataldistance(node, val, val, 
                                         0, map);
    // iterate over map.values()
    for(list list : map.values()) 
    {
      system.out.println(list);
    }
    // print "done"
    system.out.println("done");
  }
  // program to find horizonatal distance 
  public void findhorizonataldistance(node node, 
                      values min, values max, int hd,
                      map> map)
  {
    // if node is null
    if(node == null) 
      return;
    // if hd is less than min.min
    if(hd < min.min) 
      min.min=hd;
    // if hd is greater than min.min
    if(hd > max.max) 
      max.max=hd;
    // using computeifabsent
    map.computeifabsent(hd, 
             k->new arraylist()).
                                 add(node.data);
    // function call with hd equal to hd - 1
    findhorizonataldistance(node.left, min, 
                                 max, hd-1, map);
    // function call with hd equal to hd   1
    findhorizonataldistance(node.right, min, 
                                  max, hd 1, map);
  }
  // driver code
  public static void main(string[] args) 
  {
    binarytree tree = new binarytree(); 
    /* let us construct the tree shown 
                         in above diagram */
    tree.root = new node(1); 
    tree.root.left = new node(2); 
    tree.root.right = new node(3); 
    tree.root.left.left = new node(4); 
    tree.root.left.right = new node(5); 
    tree.root.right.left = new node(6); 
    tree.root.right.right = new node(7); 
    tree.root.right.left.right = new node(8); 
    tree.root.right.right.right = new node(9); 
    system.out.println("vertical order 
                             traversal is :"); 
    // function call
    tree.verticalorder(tree.root);
  }
}

如果发现任何不正确的地方,或者想分享有关上述主题的更多信息,请写评论。