📌  相关文章
📜  按垂直顺序打印二叉树 |设置 3(使用水平顺序遍历)

📅  最后修改于: 2021-10-27 07:43:03             🧑  作者: Mango

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

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

我们在下面的帖子中讨论了一种有效的方法。
按垂直顺序打印二叉树 |设置 2(基于 Hashmap 的方法)
上面的解决方案使用了前序遍历和Hashmap根据水平距离来存储节点。由于上述方法使用预序遍历,垂直线中的节点可能不会按照它们在树中出现的顺序打印。例如,上面的解决方案在下面的树中在 9 之前打印 12。请参阅此示例运行。

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

如果我们使用水平顺序遍历,我们可以确保如果像 12 这样的节点在同一条垂直线的下方,它会打印在像 9 这样的节点在垂直线的上方。

1. To maintain a hash for the branch of each node.
2. Traverse the tree in level order fashion.
3. In level order traversal, maintain a queue
   which holds, node and its vertical branch.
    * pop from queue.
    * add this node's data in vector corresponding
      to its branch in the hash.
    * if this node hash left child, insert in the 
      queue, left with branch - 1.
    * if this node hash right child, insert in the 
      queue, right with branch + 1.
C++
// C++ program for printing vertical order
// of a given binary tree usin BFS.
#include 
 
using namespace std;
 
// Structure for a binary tree node
struct Node {
    int key;
    Node *left, *right;
};
 
// A utility function to create a new node
Node* newNode(int key)
{
    Node* node = new Node;
    node->key = key;
    node->left = node->right = NULL;
    return node;
}
 
// The main function to print vertical oder of a
// binary tree with given root
void printVerticalOrder(Node* root)
{
    // Base case
    if (!root)
        return;
 
    // Create a map and store vertical oder in
    // map using function getVerticalOrder()
    map > m;
    int hd = 0;
 
    // Create queue to do level order traversal.
    // Every item of queue contains node and
    // horizontal distance.
    queue > que;
    que.push(make_pair(root, hd));
 
    while (!que.empty()) {
        // pop from queue front
        pair temp = que.front();
        que.pop();
        hd = temp.second;
        Node* node = temp.first;
 
        // insert this node's data in vector of hash
        m[hd].push_back(node->key);
 
        if (node->left != NULL)
            que.push(make_pair(node->left, hd - 1));
        if (node->right != NULL)
            que.push(make_pair(node->right, hd + 1));
    }
 
    // Traverse the map and print nodes at
    // every horigontal distance (hd)
    map >::iterator it;
    for (it = m.begin(); it != m.end(); it++) {
        for (int i = 0; i < it->second.size(); ++i)
            cout << it->second[i] << " ";
        cout << endl;
    }
}
 
// Driver program to test above functions
int main()
{
    Node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);
    root->right->left->right = newNode(8);
    root->right->right->right = newNode(9);
    root->right->right->left = newNode(10);
    root->right->right->left->right = newNode(11);
    root->right->right->left->right->right = newNode(12);
    cout << "Vertical order traversal is \n";
    printVerticalOrder(root);
    return 0;
}


Java
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.TreeMap;
 
class Node {
    int key;
    Node left, right;
    // A utility function to create a new node
    Node newNode(int key)
    {
        Node node = new Node();
        node.key = key;
        node.left = node.right = null;
        return node;
    }
}
 
class Qobj {
    int hd;
    Node node;
    Qobj(int hd, Node node)
    {
        this.hd = hd;
        this.node = node;
    }
}
 
public class VerticalOrderTraversal {
 
    // The main function to print vertical oder of a
    // binary tree with given root
    static void printVerticalOrder(Node root)
    {
        // Base case
        if (root == null)
            return;
 
        // Create a map and store vertical oder in
        // map using function getVerticalOrder()
        TreeMap > m = new TreeMap<>();
        int hd = 0;
 
        // Create queue to do level order traversal.
        // Every item of queue contains node and
        // horizontal distance.
        Queue que = new LinkedList();
        que.add(new Qobj(0, root));
 
        while (!que.isEmpty()) {
            // pop from queue front
            Qobj temp = que.poll();
            hd = temp.hd;
            Node node = temp.node;
 
            // insert this node's data in array of hash
            if (m.containsKey(hd)) {
                m.get(hd).add(node.key);
            }
            else {
                ArrayList al = new ArrayList<>();
                al.add(node.key);
                m.put(hd, al);
            }
            if (node.left != null)
                que.add(new Qobj(hd - 1, node.left));
            if (node.right != null)
                que.add(new Qobj(hd + 1, node.right));
        }
 
        // Traverse the map and print nodes at
        // every horizontal distance (hd)
        for (Map.Entry > entry : m.entrySet()) {
            ArrayList al = entry.getValue();
            for (Integer i : al)
                System.out.print(i + " ");
            System.out.println();
        }
    }
 
    // Driver program to test above functions
    public static void main(String ar[])
    {
        Node n = new Node();
        Node root;
        root = n.newNode(1);
        root.left = n.newNode(2);
        root.right = n.newNode(3);
        root.left.left = n.newNode(4);
        root.left.right = n.newNode(5);
        root.right.left = n.newNode(6);
        root.right.right = n.newNode(7);
        root.right.left.right = n.newNode(8);
        root.right.right.right = n.newNode(9);
        root.right.right.left = n.newNode(10);
        root.right.right.left.right = n.newNode(11);
        root.right.right.left.right.right = n.newNode(12);
        System.out.println("Vertical order traversal is ");
        printVerticalOrder(root);
    }
}


Python3
# python3 Program to print zigzag traversal of binary tree
import collections
# Binary tree node
class Node:
    # Constructor to create a new node
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
 
# function to print vertical order traversal of binary tree
def verticalTraverse(root):
 
    # Base case
    if root is None:
        return
 
    # Create empty queue for level order traversal
    queue = []
 
    # create a map to store nodes at a particular
    # horizontal distance
    m = {}
 
    # map to store horizontal distance of nodes
    hd_node = {}
 
    # enqueue root
    queue.append(root)
    # store the horizontal distance of root as 0
    hd_node[root] = 0
 
    m[0] = [root.data]
 
    # loop will run while queue is not empty
    while len(queue) > 0:
 
        # dequeue node from queue
        temp = queue.pop(0)
 
        if temp.left:
            # Enqueue left child
            queue.append(temp.left)
 
            # Store the horizontal distance of left node
            # hd(left child) = hd(parent) -1
            hd_node[temp.left] = hd_node[temp] - 1
            hd = hd_node[temp.left]
 
            if m.get(hd) is None:
                m[hd] = []
 
            m[hd].append(temp.left.data)
 
        if temp.right:
            # Enqueue right child
            queue.append(temp.right)
 
            # store the horizontal distance of right child
            # hd(right child) = hd(parent) + 1
            hd_node[temp.right] = hd_node[temp] + 1
            hd = hd_node[temp.right]
 
            if m.get(hd) is None:
                m[hd] = []
 
            m[hd].append(temp.right.data)
 
    # Sort the map according to horizontal distance
    sorted_m = collections.OrderedDict(sorted(m.items()))
 
    # Traverse the sorted map and print nodes at each horizontal distance
    for i in sorted_m.values():
        for j in i:
            print(j, " ", end ="")
        print()
 
# Driver program to check above function
"""
Constructed binary tree is
            1
        / \
        2     3
    / \ / \
    4     5 6     7
            \ / \
            8 10 9
                \
                11
                    \
                    12
                 
"""
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.left = Node(10)
root.right.right.right = Node(9)
root.right.right.left.right = Node(11)
root.right.right.left.right.right = Node(12)
print("Vertical order traversal is ")
verticalTraverse(root)
 
# This code is contributed by Shweta Singh


C#
// C# program to implement the
// above approach
using System;
using System.Collections;
using System.Collections.Generic;
class Node{
     
public int key;
public Node left, right;
     
// A utility function to
// create a new node
public Node newNode(int key)
{
  Node node = new Node();
  node.key = key;
  node.left = node.right =
              null;
  return node;
}
}
  
class Qobj{
  
public int hd;
public Node node;
public Qobj(int hd,
            Node node)
{
  this.hd = hd;
  this.node = node;
}
}
  
class VerticalOrderTraversal{
  
// The main function to print
// vertical oder of a binary
// tree with given root
static void printVerticalOrder(Node root)
{
  // Base case
  if (root == null)
    return;
 
  // Create a map and store vertical
  // oder in map using function
  // getVerticalOrder()
  SortedDictionary m =
                   new SortedDictionary();
 
  int hd = 0;
 
  // Create queue to do level order
  // traversal. Every item of queue
  // contains node and horizontal
  // distance.
  Queue que = new Queue();
 
  que.Enqueue(new Qobj(0, root));
 
  while(que.Count != 0)
  {
    // pop from queue front
    Qobj temp = (Qobj)que.Dequeue();
    hd = temp.hd;
    Node node = temp.node;
 
    // insert this node's data in
    // array of hash
    if (m.ContainsKey(hd))
    {
      m[hd].Add(node.key);
    }
    else
    {
      ArrayList al = new ArrayList();
      al.Add(node.key);
      m[hd] = al;
    }
 
    if (node.left != null)
      que.Enqueue(new Qobj(hd - 1,
                           node.left));
    if (node.right != null)
      que.Enqueue(new Qobj(hd + 1,
                           node.right));
  }
 
  // Traverse the map and print
  // nodes at every horizontal
  // distance (hd)
  foreach(KeyValuePair entry in m)
  {
    ArrayList al = (ArrayList)entry.Value;
     
    foreach (int i in al)
      Console.Write(i + " ");
    Console.Write("\n");
  }
}
  
// Driver code
public static void Main(string []arr)
{
  Node n = new Node();
  Node root;
  root = n.newNode(1);
  root.left = n.newNode(2);
  root.right = n.newNode(3);
  root.left.left = n.newNode(4);
  root.left.right = n.newNode(5);
  root.right.left = n.newNode(6);
  root.right.right = n.newNode(7);
  root.right.left.right = n.newNode(8);
  root.right.right.right = n.newNode(9);
  root.right.right.left = n.newNode(10);
  root.right.right.left.right = n.newNode(11);
  root.right.right.left.right.right = n.newNode(12);
  Console.Write("Vertical order traversal is \n");
  printVerticalOrder(root);
}
}
 
// This code is contributed by Rutvik_56


Javascript


输出:

Vertical order traversal is 
4  
2  
1  5  6  
3  8  10  
7  11  
9  12

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程