按垂直顺序打印二叉树|集3(使用水平顺序遍历)

给定一棵二叉树,垂直打印。下面的示例演示了垂直顺序遍历。

null
                  1         /          2       3     /       /     4     5   6    7                                 8    9                          The output of print this tree vertically will be:421 5 63 879

图片[1]-按垂直顺序打印二叉树|集3(使用水平顺序遍历)-yiteyi-C++库

我们在下面的帖子中讨论了一种有效的方法。 按垂直顺序打印二叉树|集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 using BFS.
#include <bits/stdc++.h>
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 order of a
// binary tree with given root
void printVerticalOrder(Node* root)
{
// Base case
if (!root)
return ;
// Create a map and store vertical order in
// map using function getVerticalOrder()
map< int , vector< int > > m;
int hd = 0;
// Create queue to do level order traversal.
// Every item of queue contains node and
// horizontal distance.
queue<pair<Node*, int > > que;
que.push(make_pair(root, hd));
while (!que.empty()) {
// pop from queue front
pair<Node*, int > 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 horizontal distance (hd)
map< int , vector< int > >::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 " ;
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 order of a
// binary tree with given root
static void printVerticalOrder(Node root)
{
// Base case
if (root == null )
return ;
// Create a map and store vertical order in
// map using function getVerticalOrder()
TreeMap<Integer, ArrayList<Integer> > m = new TreeMap<>();
int hd = 0 ;
// Create queue to do level order traversal.
// Every item of queue contains node and
// horizontal distance.
Queue<Qobj> que = new LinkedList<Qobj>();
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<Integer> 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<Integer, ArrayList<Integer> > entry : m.entrySet()) {
ArrayList<Integer> 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 order of a binary
// tree with given root
static void printVerticalOrder(Node root)
{
// Base case
if (root == null )
return ;
// Create a map and store vertical
// order in map using function
// getVerticalOrder()
SortedDictionary< int ,
ArrayList> m =
new SortedDictionary< int ,
ArrayList>();
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< int ,
ArrayList> entry in m)
{
ArrayList al = (ArrayList)entry.Value;
foreach ( int i in al)
Console.Write(i + " " );
Console.Write( "" );
}
}
// 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 " );
printVerticalOrder(root);
}
}
// This code is contributed by Rutvik_56


Javascript

<script>
// Javascript program to implement the
// above approach
class Node
{
constructor()
{
this .key = 0;
this .left = null ;
this .right = null ;
}
}
// A utility function to
// create a new node
function newNode(key)
{
var node = new Node();
node.key = key;
node.left = node.right =
null ;
return node;
}
class Qobj{
constructor(hd, node)
{
this .hd = hd;
this .node = node;
}
}
// The main function to print
// vertical order of a binary
// tree with given root
function printVerticalOrder(root)
{
// Base case
if (root == null )
return ;
// Create a map and store vertical
// order in map using function
// getVerticalOrder()
var m = new Map();
var hd = 0;
// Create queue to do level order
// traversal. Every item of queue
// contains node and horizontal
// distance.
var que = [];
que.push( new Qobj(0, root));
while (que.length != 0)
{
// pop from queue front
var temp = que[0];
que.shift();
hd = temp.hd;
var node = temp.node;
// insert this node's data in
// array of hash
if (m.has(hd))
{
var al = m.get(hd);
al.push(node.key);
m.set(hd, al);
}
else
{
var al = [];
al.push(node.key);
m.set(hd, al);
}
if (node.left != null )
que.push( new Qobj(hd - 1,
node.left));
if (node.right != null )
que.push( new Qobj(hd + 1,
node.right));
}
// Traverse the map and print
// nodes at every horizontal
// distance (hd)
[...m].sort((a,b)=>a[0]-b[0]).forEach(tmp => {
var al = tmp[1];
for ( var i of al)
document.write(i + " " );
document.write( "<br>" );
});
}
// Driver code
var 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);
document.write( "Vertical order traversal is <br>" );
printVerticalOrder(root);
// This code is contributed by famously.
</script>


输出:

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

上述实现的时间复杂度为O(n logn)。注意,上面的实现使用了一个映射,该映射是使用自平衡BST实现的。 我们可以使用无序映射将时间复杂度降低到O(n)。要按所需顺序打印节点,可以使用两个变量来表示最小和最大水平距离。我们可以简单地从最小水平距离迭代到最大水平距离,并从地图中得到相应的值。所以是O(n)

辅助空间:O(n)

本文由 萨希尔·查布拉(阿克库) .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享