📜  树遍历-顺序,前顺序和后顺序

📅  最后修改于: 2020-09-28 02:51:02             🧑  作者: Mango

在本教程中,您将学习不同的树遍历技术。此外,您还将在C,C++,Java和Python找到不同的树遍历方法的工作示例。

遍历树意味着访问树中的每个节点。例如,您可能想要在树中添加所有值或找到最大的值。对于所有这些操作,您将需要访问树的每个节点。

线性数据结构(如数组,堆栈,队列和链表)只有一种读取数据的方法。但是可以用不同的方式遍历像树这样的分层数据结构。

sample tree to learn tree traversal - root node contains 1 with leftchild as 12 and right child as 9. The left child of root further has left child 5 and right child 6
树遍历

让我们考虑一下如何在上面显示的图像中读取树的元素。

从顶部开始,从左到右

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

从底部开始,从左到右

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

尽管此过程有些容易,但它并不遵循树的层次结构,而仅考虑节点的深度。

相反,我们使用的遍历方法要考虑到树的基本结构,即

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

该结构节点指向左右可能有其他左,右的孩子,所以我们应该把它们当作子树,而不是子节点。

根据这种结构,每棵树都是

  • 承载数据的节点
  • 两个子树
root node with left subtree and right subtree
左右子树

请记住,我们的目标是访问每个节点,因此我们需要访问子树中的所有节点,访问根节点以及访问右子树中的所有节点。

根据执行顺序,可以有三种遍历类型。


顺序遍历

  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)

让我们可视化顺序遍历。我们从根节点开始。

outlining left subtree, right subtree and root node
左右子树

我们首先遍历左子树。我们还需要记住,完成树后,访问根节点和正确的子树。

让我们将所有这些放到堆栈中,以便我们记住。

we put the left subtree, root node and right subtree in a stack in that order so that we can display root node and traverse right subtree when we are done with left subtree
叠放

现在我们遍历指向堆栈顶部的子树。

同样,我们遵循相同的有序规则

Left subtree -> root -> right subtree

遍历左子树后,我们剩下

situation of stack after traversing left subtree, stack now contains the elements of left subtree, followed by root, followed by right child of root
最终筹码

由于节点“ 5″没有任何子树,因此我们直接打印它。之后,我们先打印其父级“ 12″,然后打印正确的子级“ 6″。

将所有内容放到堆栈上很有帮助,因为现在遍历了根节点的左子树,我们可以将其打印并转到右子树。

遍历所有元素后,我们得到的有序遍历为

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

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


Python,Java和C / C++示例

Python
爪哇
C
C +
# Tree traversal in Python


class Node:
    def __init__(self, item):
        self.left = None
        self.right = None
        self.val = item


def inorder(root):

    if root:
        # Traverse left
        inorder(root.left)
        # Traverse root
        print(str(root.val) + "->", end='')
        # Traverse right
        inorder(root.right)


def postorder(root):

    if root:
        # Traverse left
        postorder(root.left)
        # Traverse right
        postorder(root.right)
        # Traverse root
        print(str(root.val) + "->", end='')


def preorder(root):

    if root:
        # Traverse root
        print(str(root.val) + "->", end='')
        # Traverse left
        preorder(root.left)
        # Traverse right
        preorder(root.right)


root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)

print("Inorder traversal ")
inorder(root)

print("\nPreorder traversal ")
preorder(root)

print("\nPostorder traversal ")
postorder(root)
// Tree traversal in Java

class Node {
  int item;
  Node left, right;

  public Node(int key) {
  item = key;
  left = right = null;
  }
}

class BinaryTree {
  // Root of Binary Tree
  Node root;

  BinaryTree() {
  root = null;
  }

  void postorder(Node node) {
  if (node == null)
    return;

  // Traverse left
  postorder(node.left);
  // Traverse right
  postorder(node.right);
  // Traverse root
  System.out.print(node.item + "->");
  }

  void inorder(Node node) {
  if (node == null)
    return;

  // Traverse left
  inorder(node.left);
  // Traverse root
  System.out.print(node.item + "->");
  // Traverse right
  inorder(node.right);
  }

  void preorder(Node node) {
  if (node == null)
    return;

  // Traverse root
  System.out.print(node.item + "->");
  // Traverse left
  preorder(node.left);
  // Traverse right
  preorder(node.right);
  }

  public static void main(String[] args) {
  BinaryTree tree = new BinaryTree();
  tree.root = new Node(1);
  tree.root.left = new Node(12);
  tree.root.right = new Node(9);
  tree.root.left.left = new Node(5);
  tree.root.left.right = new Node(6);

  System.out.println("Inorder traversal");
  tree.inorder(tree.root);

  System.out.println("\nPreorder traversal ");
  tree.preorder(tree.root);

  System.out.println("\nPostorder traversal");
  tree.postorder(tree.root);
  }
}
// Tree traversal in C

#include 
#include 

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);
}
// Tree traversal in C++

#include 
using namespace std;

struct Node {
  int data;
  struct Node *left, *right;
  Node(int data) {
    this->data = data;
    left = right = NULL;
  }
};

// Preorder traversal
void preorderTraversal(struct Node* node) {
  if (node == NULL)
    return;

  cout << node->data << "->";
  preorderTraversal(node->left);
  preorderTraversal(node->right);
}

// Postorder traversal
void postorderTraversal(struct Node* node) {
  if (node == NULL)
    return;

  postorderTraversal(node->left);
  postorderTraversal(node->right);
  cout << node->data << "->";
}

// Inorder traversal
void inorderTraversal(struct Node* node) {
  if (node == NULL)
    return;

  inorderTraversal(node->left);
  cout << node->data << "->";
  inorderTraversal(node->right);
}

int main() {
  struct Node* root = new Node(1);
  root->left = new Node(12);
  root->right = new Node(9);
  root->left->left = new Node(5);
  root->left->right = new Node(6);

  cout << "Inorder traversal ";
  inorderTraversal(root);

  cout << "\nPreorder traversal ";
  preorderTraversal(root);

  cout << "\nPostorder traversal ";
  postorderTraversal(root);