📜  完整二叉树的迭代边界遍历

📅  最后修改于: 2021-05-31 18:52:06             🧑  作者: Mango

给定一个完整的二叉树,遍历它,以使所有边界节点从根开始按逆时针顺序访问。
例子:

Input:
               18
           /       \  
         15         30  
        /  \        /  \
      40    50    100   20
Output: 18 15 40 50 100 20 30

方法:

  • 从上到下遍历树的最左节点。 (左边界)
  • 从左到右遍历树的最底层。 (叶节点)
  • 从下到上遍历树的最右边的节点。 (右边界)

我们可以借助while循环很容易地遍历左边界,该循环检查节点何时没有左子节点。同样,我们可以借助while循环很容易地遍历右边的边界,该循环检查节点何时没有合适的子节点。
这里的主要挑战是按从左到右的顺序遍历树的最后一层。要逐级遍历,则有BFS,可以通过先将队列中的左节点推入来处理从左到右的顺序。因此,现在剩下的唯一事情就是确保它是最后一个级别。只需检查节点是否有任何子节点,并仅包括它们即可。
我们将必须特别注意不会再次遍历相同节点的特殊情况。在上面的示例中,40是左边界以及叶节点的一部分。同样,20是右边界以及叶节点的一部分。
因此,在这种情况下,我们只需要遍历两个边界的倒数第二个节点即可。另外请记住,我们不应该再次遍历根源。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
/* A binary tree node has data, pointer
   to left child and a pointer to right
   child */
struct Node {
    int data;
    struct Node *left, *right;
};
 
/* Helper function that allocates a new
   node with the given data and NULL left
   and right pointers. */
struct Node* newNode(int data)
{
    Node* temp = new Node;
 
    temp->data = data;
    temp->left = temp->right = NULL;
 
    return temp;
}
 
// Function to print the nodes of a complete
// binary tree in boundary traversal order
void boundaryTraversal(Node* root)
{
    if (root) {
 
        // If there is only 1 node print it
        // and return
        if (!(root->left) && !(root->right)) {
            cout << root->data << endl;
            return;
        }
 
        // List to store order of traversed
        // nodes
        vector list;
        list.push_back(root);
 
        // Traverse left boundary without root
        // and last node
        Node* L = root->left;
        while (L->left) {
            list.push_back(L);
            L = L->left;
        }
 
        // BFS designed to only include leaf nodes
        queue q;
        q.push(root);
        while (!q.empty()) {
            Node* temp = q.front();
            q.pop();
            if (!(temp->left) && !(temp->right)) {
                list.push_back(temp);
            }
            if (temp->left) {
                q.push(temp->left);
            }
            if (temp->right) {
                q.push(temp->right);
            }
        }
 
        // Traverse right boundary without root
        // and last node
        vector list_r;
        Node* R = root->right;
        while (R->right) {
            list_r.push_back(R);
            R = R->right;
        }
 
        // Reversing the order
        reverse(list_r.begin(), list_r.end());
 
        // Concatenating the two lists
        list.insert(list.end(), list_r.begin(),
                                 list_r.end());
 
        // Printing the node's data from the list
        for (auto i : list) {
            cout << i->data << " ";
        }
        cout << endl;
        return;
    }
}
 
// Driver code
int main()
{
 
    // Root node of the tree
    Node* root = newNode(20);
 
    root->left = newNode(8);
    root->right = newNode(22);
 
    root->left->left = newNode(4);
    root->left->right = newNode(12);
 
    root->right->left = newNode(10);
    root->right->right = newNode(25);
 
    boundaryTraversal(root);
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
 
class GFG{
 
/* A binary tree node has data, pointer
   to left child and a pointer to right
   child */
static class Node {
    int data;
    Node left, right;
};
 
/* Helper function that allocates a new
   node with the given data and null left
   and right pointers. */
static Node newNode(int data)
{
    Node temp = new Node();
 
    temp.data = data;
    temp.left = temp.right = null;
 
    return temp;
}
 
// Function to print the nodes of a complete
// binary tree in boundary traversal order
static void boundaryTraversal(Node root)
{
    if (root != null) {
 
        // If there is only 1 node print it
        // and return
        if ((root.left == null) && (root.right == null)) {
            System.out.print(root.data +"\n");
            return;
        }
 
        // List to store order of traversed
        // nodes
        Vector list = new Vector();
        list.add(root);
 
        // Traverse left boundary without root
        // and last node
        Node L = root.left;
        while (L.left != null) {
            list.add(L);
            L = L.left;
        }
 
        // BFS designed to only include leaf nodes
        Queue q = new LinkedList<>();
        q.add(root);
        while (!q.isEmpty()) {
            Node temp = q.peek();
            q.remove();
            if ((temp.left == null) && (temp.right == null)) {
                list.add(temp);
            }
            if (temp.left != null) {
                q.add(temp.left);
            }
            if (temp.right != null) {
                q.add(temp.right);
            }
        }
 
        // Traverse right boundary without root
        // and last node
        Vector list_r = new Vector();
        Node R = root.right;
        while (R.right != null) {
            list_r.add(R);
            R = R.right;
        }
 
        // Reversing the order
        Collections.reverse(list_r);
 
        // Concatenating the two lists
        list.addAll(list_r);
 
        // Printing the node's data from the list
        for (Node i : list) {
            System.out.print(i.data + " ");
        }
        System.out.println();
        return;
    }
}
 
// Driver code
public static void main(String[] args)
{
 
    // Root node of the tree
    Node root = newNode(20);
 
    root.left = newNode(8);
    root.right = newNode(22);
 
    root.left.left = newNode(4);
    root.left.right = newNode(12);
 
    root.right.left = newNode(10);
    root.right.right = newNode(25);
 
    boundaryTraversal(root);
}
}
 
// This code is contributed by Princi Singh


Python
# Python implementation of the approach
from collections import deque
  
# A binary tree node
class Node:
  
    # A constructor for making a new node
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
  
# Function to print the nodes of a complete
# binary tree in boundary traversal order
def boundaryTraversal(root):
    # If there is only 1 node print it and return
    if root:
        if not root.left and not root.right:
            print (root.data)
            return
  
        # List to store order of traversed nodes
        list = []
        list.append(root)
  
        # Traverse left boundary without root
        # and last node
        temp = root.left
        while temp.left:
            list.append(temp)
            temp = temp.left
  
        # BFS designed to only include leaf nodes
        q = deque()
        q.append(root)
        while len(q) != 0:
            x = q.pop()
            if not x.left and not x.right:
                list.append(x)
            if x.right:
                q.append(x.right)
            if x.left:
                q.append(x.left)
  
        # Traverse right boundary without root
        # and last node
        list_r = []
        temp = root.right
        while temp.right:
            list.append(temp)
            temp = temp.right
  
        # Reversing the order
        list_r = list_r[::-1]
  
        # Concatenating the two lists
        list += list_r
  
        # Printing the node's data from the list
        print (" ".join([str(i.data) for i in list]))
    return
  
# Root node of the tree
  
root = Node(20)
  
root.left = Node(8)
root.right = Node(22)
  
root.left.left = Node(4)
root.left.right = Node(12)
 
root.right.left = Node(10)
root.right.right = Node(25)
  
boundaryTraversal(root)


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
 
/* A binary tree node has data, pointer
   to left child and a pointer to right
   child */
class Node
{
    public int data;
    public Node left, right;
};
 
/* Helper function that allocates a new
   node with the given data and null left
   and right pointers. */
static Node newNode(int data)
{
    Node temp = new Node();
    temp.data = data;
    temp.left = temp.right = null;
    return temp;
}
 
// Function to print the nodes of a complete
// binary tree in boundary traversal order
static void boundaryTraversal(Node root)
{
    if (root != null)
    {
 
        // If there is only 1 node print it
        // and return
        if ((root.left == null) &&
            (root.right == null))
        {
            Console.Write(root.data + "\n");
            return;
        }
 
        // List to store order of traversed
        // nodes
        List list = new List();
        list.Add(root);
 
        // Traverse left boundary without root
        // and last node
        Node L = root.left;
        while (L.left != null)
        {
            list.Add(L);
            L = L.left;
        }
 
        // BFS designed to only include leaf nodes
        Queue q = new Queue();
        q.Enqueue(root);
        while (q.Count != 0)
        {
            Node temp = q.Peek();
            q.Dequeue();
            if ((temp.left == null) &&
                (temp.right == null))
            {
                list.Add(temp);
            }
            if (temp.left != null)
            {
                q.Enqueue(temp.left);
            }
            if (temp.right != null)
            {
                q.Enqueue(temp.right);
            }
        }
 
        // Traverse right boundary without root
        // and last node
        List list_r = new List();
        Node R = root.right;
        while (R.right != null)
        {
            list_r.Add(R);
            R = R.right;
        }
 
        // Reversing the order
        list_r.Reverse();
 
        // Concatenating the two lists
        list.InsertRange(list.Count-1, list_r);
 
        // Printing the node's data from the list
        foreach (Node i in list)
        {
            Console.Write(i.data + " ");
        }
        Console.WriteLine();
        return;
    }
}
 
// Driver code
public static void Main(String[] args)
{
 
    // Root node of the tree
    Node root = newNode(20);
    root.left = newNode(8);
    root.right = newNode(22);
    root.left.left = newNode(4);
    root.left.right = newNode(12);
    root.right.left = newNode(10);
    root.right.right = newNode(25);
    boundaryTraversal(root);
}
}
 
// This code is contributed by 29AjayKumar


输出:
20 8 4 12 10 25 22
想要从精选的最佳视频中学习并解决问题,请查看有关从基础到高级C++的C++基础课程以及有关语言和STL的C++ STL课程。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”