简明易懂的算法文章-了解树遍历-中序,前序和后序

    在本教程中,您将学习不同的树遍历技术。此外,您还将找到C中树遍历方法的工作示例。(C++,Java和Python示例见原文)
    遍历树意味着访问树中的每个节点。例如,您可能想把所有值添加到树中或找到最大的值。对于所有这些操作,您将需要访问树的每个节点。
    线性数据结构(如数组,堆栈,队列和链表)只有一种读取数据的方法。但是像树这样的分层数据结构可以以不同的方式遍历。
在这里插入图片描述
    让我们考虑一下如何在上面显示的图像中读取树的元素。
    从上到下,从左到右

1 -> 12 -> 5 -> 6 -> 9

    从底部开始,从左到右

5 -> 6 -> 12 -> 9 -> 1

    虽然这个过程有点简单,但它不考虑树的层次结构,只考虑节点的深度。
    取而代之的是,我们使用遍历方法来考虑树的基本结构,即

struct node {
    
    
    int data;
    struct node* left;
    struct node* right;
}

    由 left 和 right 指向的struct节点可能有其他的 left 和 right 子节点,因此我们应该将它们看作子树而不是子节点。
    根据这种结构,每棵树都是

  • 承载数据的节点
  • 两个子树
    在这里插入图片描述
        请记住,我们的目标是访问每个节点,因此我们需要访问子树中的所有节点,访问根节点以及访问右子树中的所有节点。
        根据执行顺序,可以有三种遍历类型。

中序遍历

  1. 首先,访问左侧子树中的所有节点
  2. 然后是根节点
  3. 访问右侧子树中的所有节点
inorder(root->left)
display(root->data)
inorder(root->right)

前序遍历

  1. 访问根节点
  2. 访问左侧子树中的所有节点
  3. 访问右侧子树中的所有节点
display(root->data)
preorder(root->left)
preorder(root->right)

后序遍历

  1. 访问左侧子树中的所有节点
  2. 访问右侧子树中的所有节点
  3. 访问根节点
postorder(root->left)
postorder(root->right)
display(root->data)

    让我们可视化中序遍历。我们从根节点开始。
在这里插入图片描述
    我们首先遍历左子树。我们还需要记住在这个树完成时访问根节点和正确的子树。
    让我们将所有这些放到堆栈中,这样我们就记住了。
在这里插入图片描述
    现在我们遍历指向堆栈顶部的子树。
    同样,我们遵循相同的有序规则。

Left subtree -> root -> right subtree

    遍历左子树后,我们将得到:
在这里插入图片描述
    由于节点“ 5”没有任何子树,因此我们直接打印它。之后,我们先打印其父级“ 12”,然后打印正确的子级“ 6”。
    将所有内容放在堆栈中很有帮助,因为现在已经遍历了根节点的左子树,我们可以打印它并转到右子树。
    在遍历所有元素之后,我们得到的中序遍历为

5 -> 12 -> 6 -> 1 -> 9

    我们不必自己创建堆栈,因为递归可以为我们保持正确的顺序。

C 示例

// Tree traversal in C

#include <stdio.h>
#include <stdlib.h>

struct node {
    
    
  int item;
  struct node* left;
  struct node* right;
};

// Inorder traversal
void inorderTraversal(struct node* root) {
    
    
  if (root == NULL) return;
  inorderTraversal(root->left);
  printf("%d ->", root->item);
  inorderTraversal(root->right);
}

// preorderTraversal traversal
void preorderTraversal(struct node* root) {
    
    
  if (root == NULL) return;
  printf("%d ->", root->item);
  preorderTraversal(root->left);
  preorderTraversal(root->right);
}

// postorderTraversal traversal
void postorderTraversal(struct node* root) {
    
    
  if (root == NULL) return;
  postorderTraversal(root->left);
  postorderTraversal(root->right);
  printf("%d ->", root->item);
}

// Create a new Node
struct node* createNode(value) {
    
    
  struct node* newNode = malloc(sizeof(struct node));
  newNode->item = value;
  newNode->left = NULL;
  newNode->right = NULL;

  return newNode;
}

// Insert on the left of the node
struct node* insertLeft(struct node* root, int value) {
    
    
  root->left = createNode(value);
  return root->left;
}

// Insert on the right of the node
struct node* insertRight(struct node* root, int value) {
    
    
  root->right = createNode(value);
  return root->right;
}

int main() {
    
    
  struct node* root = createNode(1);
  insertLeft(root, 12);
  insertRight(root, 9);

  insertLeft(root->left, 5);
  insertRight(root->left, 6);

  printf("Inorder traversal \n");
  inorderTraversal(root);

  printf("\nPreorder traversal \n");
  preorderTraversal(root);

  printf("\nPostorder traversal \n");
  postorderTraversal(root);
}

编译执行,结果为:

Inorder traversal 
5 ->12 ->6 ->1 ->9 ->
Preorder traversal 
1 ->12 ->5 ->6 ->9 ->
Postorder traversal 
5 ->6 ->12 ->9 ->1 ->

参考文档

https://www.programiz.com/dsa/tree-traversal

猜你喜欢

转载自blog.csdn.net/zsx0728/article/details/110916252