给定一个二叉树,垂直打印它。以下示例说明了垂直顺序遍历。
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 现场工作专业课程和学生竞争性编程现场课程。