📜  侧向遍历完整的二叉树

📅  最后修改于: 2021-04-22 00:33:40             🧑  作者: Mango

给定完整的二叉树,任务是按照以下模式打印元素。让我们考虑这棵树为:

通过以下方式遍历该树:

上面的树的输出是:

1 3 7 11 10 9 8 4 5 6 2

方法:想法是使用修改的广度优先搜索函数将向量中每个级别的所有节点存储在向量数组中。与此一起,需要遍历树的最大级别也存储在一个变量中。完成此预计算任务后,请按照以下步骤操作以获取所需的答案:

  1. 创建一个向量tree [] ,其中tree [i]将在i级别存储树的所有节点。
  2. 取一个整数变量k ,它跟踪正在遍历的级数,而另一个整数变量路径,它跟踪已经完成的循环数。还创建了一个标志变量来跟踪树的遍历方向。
  3. 现在,开始在每个级别上打印最右边的节点,直到达到最大级别
  4. 由于已达到最大水平,因此必须更改方向。在最后一级,从最右到左打印元素。并且maxLevel变量的值必须递减。
  5. 当树从下层遍历到上层时,将打印最右边的元素。由于在下一次迭代中, maxlevel值已更改,因此可确保不会再次遍历最后一级中已访问的节点。

    重复上述步骤,直到遍历整个树为止。

下面是上述方法的实现:

C++
// C++ program to print sideways
// traversal of complete binary tree
  
#include 
using namespace std;
  
const int sz = 1e5;
int maxLevel = 0;
  
// Adjacency list representation
// of the tree
vector tree[sz + 1];
  
// Boolean array to mark all the
// vertices which are visited
bool vis[sz + 1];
  
// Integer array to store the level
// of each node
int level[sz + 1];
  
// Array of vector where ith index
// stores all the nodes at level i
vector nodes[sz + 1];
  
// Utility function to create an
// edge between two vertices
void addEdge(int a, int b)
{
  
    // Add a to b's list
    tree[a].push_back(b);
  
    // Add b to a's list
    tree[b].push_back(a);
}
  
// Modified Breadth-First Function
void bfs(int node)
{
  
    // Create a queue of {child, parent}
    queue > qu;
  
    // Push root node in the front of
    // the queue and mark as visited
    qu.push({ node, 0 });
    nodes[0].push_back(node);
    vis[node] = true;
    level[1] = 0;
  
    while (!qu.empty()) {
  
        pair p = qu.front();
  
        // Dequeue a vertex from queue
        qu.pop();
        vis[p.first] = true;
  
        // Get all adjacent vertices of the dequeued
        // vertex s. If any adjacent has not
        // been visited then enqueue it
        for (int child : tree[p.first]) {
  
            if (!vis[child]) {
                qu.push({ child, p.first });
                level[child] = level[p.first] + 1;
                maxLevel = max(maxLevel, level[child]);
                nodes[level[child]].push_back(child);
            }
        }
    }
}
  
// Utility Function to display the pattern
void display()
{
    // k represents the level no.
    // cycle represents how many
    // cycles has been completed
    int k = 0, path = 0;
    int condn = (maxLevel) / 2 + 1;
    bool flag = true;
  
    // While there are nodes left to traverse
    while (condn--) {
  
        if (flag) {
  
            // Traversing whole level from
            // left to right
            int j = nodes[k].size() - 1;
            for (j = 0; j < nodes[k].size() - path; j++)
                cout << nodes[k][j] << " ";
  
            // Moving to new level
            k++;
  
            // Traversing rightmost unvisited
            // element  in path path as we
            // move up to down
            while (k < maxLevel) {
  
                j = nodes[k].size() - 1;
                cout << nodes[k][j - path] << " ";
                k++;
            }
  
            j = nodes[k].size() - 1;
            if (k > path)
                for (j -= path; j >= 0; j--)
                    cout << nodes[k][j] << " ";
  
            // Setting value of new maximum
            // level upto which we have to traverse
            // next time
            maxLevel--;
  
            // Updating from which level to
            // start new path
            k--;
            path++;
  
            flag = !flag;
        }
        else {
  
            // Traversing each element of remaing
            // last level from left to right
            int j = nodes[k].size() - 1;
            for (j = 0; j < nodes[k].size() - path; j++)
                cout << nodes[k][j] << " ";
  
            // Decrementing value of Max level
            maxLevel--;
  
            k--;
  
            // Traversing rightmost unvisited
            // element  in path as we
            // move down to up
            while (k > path) {
  
                int j = nodes[k].size() - 1;
                cout << nodes[k][j - path] << " ";
                k--;
            }
  
            j = nodes[k].size() - 1;
  
            if (k == path)
                for (j -= path; j >= 0; j--)
                    cout << nodes[k][j] << " ";
  
            path++;
  
            // Updating the level number from which
            // a new cycle has to be started
            k++;
            flag = !flag;
        }
    }
}
  
// Driver code
int main()
{
  
    // Initialising  the above mentioned
    // complete binary tree
    for (int i = 1; i <= 5; i++) {
  
        // Adding edge to a binary tree
        addEdge(i, 2 * i);
        addEdge(i, 2 * i + 1);
    }
  
    // Calling modified bfs function
    bfs(1);
  
    display();
  
    return 0;
}


Java
// Java program to print sideways
// traversal of complete binary tree
import java.util.*;
  
class GFG
{
      
static class pair
{ 
    int first, second; 
    public pair(int first, int second) 
    { 
        this.first = first; 
        this.second = second; 
    } 
} 
static int sz = (int) 1e5;
static int maxLevel = 0;
  
// Adjacency list representation
// of the tree
static Vector []tree = new Vector[sz + 1];
  
// Boolean array to mark all the
// vertices which are visited
static boolean []vis = new boolean[sz + 1];
  
// Integer array to store the level
// of each node
static int []level = new int[sz + 1];
  
// Array of vector where ith index
// stores all the nodes at level i
static Vector []nodes = new Vector[sz + 1];
  
// Utility function to create an
// edge between two vertices
static void addEdge(int a, int b)
{
  
    // Add a to b's list
    tree[a].add(b);
  
    // Add b to a's list
    tree[b].add(a);
}
  
// Modified Breadth-First Function
static void bfs(int node)
{
  
    // Create a queue of {child, parent}
    Queue qu = new LinkedList<>();
  
    // Push root node in the front of
    // the queue and mark as visited
    qu.add(new pair( node, 0 ));
    nodes[0].add(node);
    vis[node] = true;
    level[1] = 0;
  
    while (!qu.isEmpty()) {
  
        pair p = qu.peek();
  
        // Dequeue a vertex from queue
        qu.remove();
        vis[p.first] = true;
  
        // Get all adjacent vertices of the dequeued
        // vertex s. If any adjacent has not
        // been visited then enqueue it
        for (int child : tree[p.first]) {
  
            if (!vis[child]) {
                qu.add(new pair( child, p.first ));
                level[child] = level[p.first] + 1;
                maxLevel = Math.max(maxLevel, level[child]);
                nodes[level[child]].add(child);
            }
        }
    }
}
  
// Utility Function to display the pattern
static void display()
{
    // k represents the level no.
    // cycle represents how many
    // cycles has been completed
    int k = 0, path = 0;
    int condn = (maxLevel) / 2 + 1;
    boolean flag = true;
  
    // While there are nodes left to traverse
    while (condn-- > 0) {
  
        if (flag) {
  
            // Traversing whole level from
            // left to right
            int j = nodes[k].size() - 1;
            for (j = 0; j < nodes[k].size() - path; j++)
                System.out.print(nodes[k].get(j)+ " ");
  
            // Moving to new level
            k++;
  
            // Traversing rightmost unvisited
            // element in path path as we
            // move up to down
            while (k < maxLevel) {
  
                j = nodes[k].size() - 1;
                System.out.print(nodes[k].get(j - path)+ " ");
                k++;
            }
  
            j = nodes[k].size() - 1;
            if (k > path)
                for (j -= path; j >= 0; j--)
                    System.out.print(nodes[k].get(j)+ " ");
  
            // Setting value of new maximum
            // level upto which we have to traverse
            // next time
            maxLevel--;
  
            // Updating from which level to
            // start new path
            k--;
            path++;
  
            flag = !flag;
        }
        else {
  
            // Traversing each element of remaing
            // last level from left to right
            int j = nodes[k].size() - 1;
            for (j = 0; j < nodes[k].size() - path; j++)
                System.out.print(nodes[k].get(j)+ " ");
  
            // Decrementing value of Max level
            maxLevel--;
  
            k--;
  
            // Traversing rightmost unvisited
            // element in path as we
            // move down to up
            while (k > path) {
  
                int c = nodes[k].size() - 1;
                System.out.print(nodes[k].get(c - path)+ " ");
                k--;
            }
  
            j = nodes[k].size() - 1;
  
            if (k == path)
                for (j -= path; j >= 0; j--)
                    System.out.print(nodes[k].get(j)+ " ");
  
            path++;
  
            // Updating the level number from which
            // a new cycle has to be started
            k++;
            flag = !flag;
        }
    }
}
  
// Driver code
public static void main(String[] args)
{
  
    for (int i = 0; i < tree.length; i++) {
        tree[i] = new Vector<>();
        nodes[i] = new Vector<>();
    }
      
    // Initialising the above mentioned
    // complete binary tree
    for (int i = 1; i <= 5; i++) {
  
        // Adding edge to a binary tree
        addEdge(i, 2 * i);
        addEdge(i, 2 * i + 1);
    }
  
    // Calling modified bfs function
    bfs(1);
  
    display();
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 program to prsideways
# traversal of complete binary tree
from collections import deque
  
sz = 10**5
maxLevel = 0
  
# Adjacency list representation
# of the tree
tree = [[] for i in range(sz + 1)]
  
# Boolean array to mark all the
# vertices which are visited
vis = [False]*(sz + 1)
  
# Integer array to store the level
# of each node
level = [0]*(sz + 1)
  
# Array of vector where ith index
# stores all the nodes at level i
nodes = [[] for i in range(sz + 1)]
  
# Utility function to create an
# edge between two vertices
def addEdge(a, b):
  
    # Add a to b's list
    tree[a].append(b)
  
    # Add b to a's list
    tree[b].append(a)
  
# Modified Breadth-First Function
def bfs(node):
    global maxLevel
  
    # Create a queue of {child, parent}
    qu = deque()
  
    # Push root node in the front of
    # the queue and mark as visited
    qu.append([node, 0])
    nodes[0].append(node)
    vis[node] = True
    level[1] = 0
  
    while (len(qu) > 0):
  
        p = qu.popleft()
  
        # Dequeue a vertex from queue
        vis[p[0]] = True
  
        # Get all adjacent vertices of the dequeued
        # vertex s. If any adjacent has not
        # been visited then enqueue it
        for child in tree[p[0]]:
  
            if (vis[child] == False):
                qu.append([child, p[0]])
                level[child] = level[p[0]] + 1
                maxLevel = max(maxLevel, level[child])
                nodes[level[child]].append(child)
  
# Utility Function to display the pattern
def display():
    global maxLevel
      
    # k represents the level no.
    # cycle represents how many
    # cycles has been completed
    k = 0
    path = 0
    condn = (maxLevel) // 2 + 1
    flag = True
  
    # While there are nodes left to traverse
    while (condn):
  
        if (flag):
  
            # Traversing whole level from
            # left to right
            j = len(nodes[k]) - 1
            for j in range(len(nodes[k])- path):
                print(nodes[k][j],end=" ")
  
            # Moving to new level
            k += 1
  
            # Traversing rightmost unvisited
            # element in path path as we
            # move up to down
            while (k < maxLevel):
  
                j = len(nodes[k]) - 1
                print(nodes[k][j - path], end=" ")
                k += 1
  
            j = len(nodes[k]) - 1
            if (k > path):
                while j >= 0:
                    j -= path
                    print(nodes[k][j], end=" ")
                    j -= 1
  
            # Setting value of new maximum
            # level upto which we have to traverse
            # next time
            maxLevel -= 1
  
            # Updating from which level to
            # start new path
            k -= 1
            path += 1
  
            flag = not flag
        else:
  
            # Traversing each element of remaing
            # last level from left to right
            j = len(nodes[k]) - 1
            for j in range(len(nodes[k]) - path):
                print(nodes[k][j], end=" ")
  
            # Decrementing value of Max level
            maxLevel -= 1
  
            k -= 1
  
            # Traversing rightmost unvisited
            # element in path as we
            # move down to up
            while (k > path):
  
                j = len(nodes[k]) - 1
                print(nodes[k][j - path], end=" ")
                k -= 1
  
            j = len(nodes[k]) - 1
  
            if (k == path):
                while j >= 0:
                    j -= path
                    print(nodes[k][j],end=" ")
                    j -= 1
  
            path += 1
  
            # Updating the level number from which
            # a new cycle has to be started
            k += 1
            flag = not flag
        condn -= 1
  
# Driver code
if __name__ == '__main__':
  
    # Initialising the above mentioned
    # complete binary tree
    for i in range(1,6):
  
        # Adding edge to a binary tree
        addEdge(i, 2 * i)
        addEdge(i, 2 * i + 1)
  
    # Calling modified bfs function
    bfs(1)
  
    display()
  
# This code is contributed by mohit kumar 29


C#
// C# program to print sideways
// traversal of complete binary tree
using System;
using System.Collections.Generic;
  
class GFG
{
       
class pair
{ 
    public int first, second; 
    public pair(int first, int second) 
    { 
        this.first = first; 
        this.second = second; 
    } 
} 
static int sz = (int) 1e5;
static int maxLevel = 0;
   
// Adjacency list representation
// of the tree
static List []tree = new List[sz + 1];
   
// Boolean array to mark all the
// vertices which are visited
static bool []vis = new bool[sz + 1];
   
// int array to store the level
// of each node
static int []level = new int[sz + 1];
   
// Array of vector where ith index
// stores all the nodes at level i
static List []nodes = new List[sz + 1];
   
// Utility function to create an
// edge between two vertices
static void addEdge(int a, int b)
{
   
    // Add a to b's list
    tree[a].Add(b);
   
    // Add b to a's list
    tree[b].Add(a);
}
   
// Modified Breadth-First Function
static void bfs(int node)
{
   
    // Create a queue of {child, parent}
    Queue qu = new Queue();
   
    // Push root node in the front of
    // the queue and mark as visited
    qu.Enqueue(new pair( node, 0 ));
    nodes[0].Add(node);
    vis[node] = true;
    level[1] = 0;
   
    while (qu.Count != 0) {
   
        pair p = qu.Peek();
   
        // Dequeue a vertex from queue
        qu.Dequeue();
        vis[p.first] = true;
   
        // Get all adjacent vertices of the dequeued
        // vertex s. If any adjacent has not
        // been visited then enqueue it
        foreach (int child in tree[p.first]) {
   
            if (!vis[child]) {
                qu.Enqueue(new pair( child, p.first ));
                level[child] = level[p.first] + 1;
                maxLevel = Math.Max(maxLevel, level[child]);
                nodes[level[child]].Add(child);
            }
        }
    }
}
   
// Utility Function to display the pattern
static void display()
{
    // k represents the level no.
    // cycle represents how many
    // cycles has been completed
    int k = 0, path = 0;
    int condn = (maxLevel) / 2 + 1;
    bool flag = true;
   
    // While there are nodes left to traverse
    while (condn-- > 0) {
   
        if (flag) {
   
            // Traversing whole level from
            // left to right
            int j = nodes[k].Count - 1;
            for (j = 0; j < nodes[k].Count - path; j++)
                Console.Write(nodes[k][j]+ " ");
   
            // Moving to new level
            k++;
   
            // Traversing rightmost unvisited
            // element in path path as we
            // move up to down
            while (k < maxLevel) {
   
                j = nodes[k].Count - 1;
                Console.Write(nodes[k][j - path]+ " ");
                k++;
            }
   
            j = nodes[k].Count - 1;
            if (k > path)
                for (j -= path; j >= 0; j--)
                    Console.Write(nodes[k][j]+ " ");
   
            // Setting value of new maximum
            // level upto which we have to traverse
            // next time
            maxLevel--;
   
            // Updating from which level to
            // start new path
            k--;
            path++;
   
            flag = !flag;
        }
        else {
   
            // Traversing each element of remaing
            // last level from left to right
            int j = nodes[k].Count - 1;
            for (j = 0; j < nodes[k].Count - path; j++)
                Console.Write(nodes[k][j]+ " ");
   
            // Decrementing value of Max level
            maxLevel--;
   
            k--;
   
            // Traversing rightmost unvisited
            // element in path as we
            // move down to up
            while (k > path) {
   
                int c = nodes[k].Count - 1;
                Console.Write(nodes[k]+ " ");
                k--;
            }
   
            j = nodes[k].Count - 1;
   
            if (k == path)
                for (j -= path; j >= 0; j--)
                    Console.Write(nodes[k][j]+ " ");
   
            path++;
   
            // Updating the level number from which
            // a new cycle has to be started
            k++;
            flag = !flag;
        }
    }
}
   
// Driver code
public static void Main(String[] args)
{
   
    for (int i = 0; i < tree.Length; i++) {
        tree[i] = new List();
        nodes[i] = new List();
    }
       
    // Initialising the above mentioned
    // complete binary tree
    for (int i = 1; i <= 5; i++) {
   
        // Adding edge to a binary tree
        addEdge(i, 2 * i);
        addEdge(i, 2 * i + 1);
    }
   
    // Calling modified bfs function
    bfs(1);
   
    display();
}
}
  
// This code contributed by PrinciRaj1992


输出:
1 3 7 11 10 9 8 4 5 6 2