C++ 二叉树的顺时针三角形遍历

C++ 二叉树的顺时针三角形遍历

在这个问题中,我们将创建一棵完全二叉树并以顺时针的方向遍历它。

对于顺时针遍历,我们可以将其视为遍历树的边界。例如,我们可以首先遍历树的外边界。然后,我们可以移除已经访问的节点并遍历树的内边界。通过这种方式,我们需要进行min(height/2, width/2)次遍历给定的二叉树。

问题陈述

我们已经给定了一棵包含N个节点的完全二叉树,需要以顺时针的方向遍历它。

示例示范

输入

n = 3
    1
 /   \
2     3

输出

1, 3, 2

解释

顺时针遍历的顺序是1,3和2。

输入

n = 7
     1
   /   \
   2    3
 /  \  /  \
4   5 6    7

输出

1, 3, 7, 6, 5, 4, 2

解释

首先,我们遍历了右边界,之后是底部边界,再然后是左边界。

输入

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

输出

1, 3, 7, 11, 10, 9, 8, 4, 2, 6, 5

解释

它以顺时针的方式遍历。我们需要保持遍历内部节点。

方法1

在这个方法中,我们将使用列表创建一个完全二叉树。之后,我们将创建一个二维列表,并使用它来分别存储每个层级的节点列表。同时,我们会找到二叉树的高度。

之后,我们将遍历树的右边界、底边界和左边界。此外,我们将进行totalLevels/2次循环迭代,以循环遍历所有层级。

算法

  • 步骤 1 - 执行 createBinaryTree() 函数,创建一个包含 n 个节点的完全二叉树。

  • 步骤 1.2 - 在 createBinaryTree() 函数中,使用 for 循环进行遍历,并在循环中将 ‘isChild’ 定义为 false 值。

  • 步骤 1.3 - 如果 2p 小于等于 n,添加一个边连接 p 和 2p 节点。在这里,我们使用向量列表来创建二叉树。所以,在 2p 的位置插入 p,以添加 p 和 2p 之间的边。同时,将 isChild 设置为 true。

  • 步骤 1.4 - 如果 2p + 1 小于等于 n,插入一个边连接 p 和 2p + 1 节点。同时,更新 isChild 为 true。

  • 步骤 1.5 - (此步骤未提供完整的描述,请提供完整描述以便翻译)

    • 如果 isChild 是 false,跳出循环。

    • 第2步 − 现在,调用 executeBFS() 函数以获取列表中每个级别的节点。

    • 第2.1步 − 定义队列来存储单个节点及其父节点的对。同时将头节点插入队列中。还使用 nodes[][] 列表来存储每个级别的节点。 visited[] 列表用于标记具有 true 布尔值的访问过的节点。 level[] 列表存储每个节点的级别编号。

    • 第2.2步 − 遍历队列。

    • 第2.3步 − 从队列中弹出第一个对,并标记节点已访问。

    • 第2.4步 − 遍历当前节点的所有相邻节点。

    • 步骤2.4.1 - 如果相邻节点未被访问,则将其与父节点一起插入队列中。同时,将子节点的层级存储在level[]列表中。

    • 步骤2.4.2 - 如果max_level值低于level[child],则更新max_level值。

    • 步骤2.4.3 - 将当前节点推入nodes[level[child]]列表中。

现在,我们根据层级在nodes[][]列表中获得了树的每个节点。

  • 步骤3 - 调用showClockWise()函数以顺时针方向遍历树。

  • 步骤3.1 - 定义levelNo和cycle变量,并将它们初始化为0。

  • 步骤3.2 − Finally, print the value of the root node.

将周期值递增1,并使用周期+1更新levelNo。

例子

#include <bits/stdc++.h>
using namespace std;

void insertEdge(int start, int end, vector<int> tree[]) {
   tree[start].push_back(end);
   tree[end].push_back(start);
}
void createBinaryTree(int n, vector<int> tree[]) {
   // Create a complete binary tree
   for (int p = 1;; p++) {
      // Add edges to the tree
      bool isChild = false;
      if (2 * p <= n) {
         insertEdge(p, 2 * p, tree);
         isChild = true;
      }
      if (2 * p + 1 <= n) {
         insertEdge(p, 2 * p + 1, tree);
         isChild = true;
      }
      if (!isChild)
         break;
   }
}
void executeBFS(int root, vector<int> tree[], bool visited[], int level[], vector<int> nodes[], int &max_level) {
   queue<pair<int, int>> que;
   // Inserting the root node in the queue and mark it as visited
   que.push({root, 0});
   nodes[0].push_back(root);
   visited[root] = true;
   level[1] = 0;
   while (!que.empty()) {
      pair<int, int> temp = que.front();
      que.pop();
      visited[temp.first] = true;
      // Get adjacent vertices
      for (int child : tree[temp.first]) {
         if (!visited[child]) {
            que.push({child, temp.first});
            level[child] = level[temp.first] + 1;
            // Updating the max level
            max_level = max(max_level, level[child]);
            // Store nodes according to level wise
            nodes[level[child]].push_back(child);
         }
      }
   }
}
void showClockWise(vector<int> nodes[], int max_level) {
   int levelNo = 0, cycle = 0;
   while (cycle - 1 <= max_level / 2) {
      // Traverse right nodes
      while (levelNo < max_level - cycle) {
         int q = nodes[levelNo].size() - 1;
         cout << nodes[levelNo][q - cycle] << " ";
         levelNo++;
      }
      // Traverse bottom nodes from right -> left
      if (levelNo == max_level - cycle) {
         int q = nodes[levelNo].size() - 1;
         for (q -= cycle; q >= cycle; q--)
            cout << nodes[levelNo][q] << " ";
      }
      levelNo--;
      // Traverse left nodes
      while (levelNo > cycle) {
         cout << nodes[levelNo][cycle] << " ";
         levelNo--;
      }
      // Increment cycle
      cycle++;
      // Update next level to start from
      levelNo = cycle + 1;
   }
}
int main() {
   // Number of vertices
   int n = 7;
   const int size = 1e5;
   int max_level = 0;
   vector<int> tree[size + 1];
   bool visited[size + 1];
   int level[size + 1];
   vector<int> nodes[size + 1];
   createBinaryTree(n, tree);
   executeBFS(1, tree, visited, level, nodes, max_level);
   showClockWise(nodes, max_level);
   return 0;
}

输出

1 3 7 6 5 4 2
  • 时间复杂度 - O(N)

  • 空间复杂度 - O(N)

结论

程序员可以尝试以逆时针方向遍历二叉树。为此,他们可以首先遍历左边界,然后遍历底部,最后遍历右边界。另外,他们可以逐个遍历内部边界,就像我们在这个问题中做的一样。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程