Tree Traversal (Inorder, Preorder, Postorder)

โšก Smart sammanfattning

Trรคdgenomgรฅngar besรถker varje nod i ett binรคrt trรคd i en definierad ordning. Denna resurs fรถrklarar bredd-fรถrst (nivรฅordning) och de tre djup-fรถrst-metoderna โ€“ inorder, preorder och postorder โ€“ med steg-fรถr-steg-exempel, pseudokod och kompletta implementeringar i Python, C och C++.

  • ???? Tvรฅ kategorier: Traversaler delas upp i bredd fรถrst (nivรฅordning) och djup fรถrst (inordning, fรถrordning, efterordning).
  • โฌ…๏ธ I ordning: Besรถker vรคnster undertrรคd, rot och sedan hรถger undertrรคd; pรฅ en BST returnerar den vรคrden i sorterad ordning.
  • ๐Ÿ” Fรถrboka: Besรถker fรถrst roten, sedan vรคnster och hรถger undertrรคd; anvรคndbart fรถr att kopiera ett trรคd.
  • ๐Ÿ”š Postorder: Besรถker vรคnster och hรถger undertrรคd fรถre roten; anvรคndbart fรถr att ta bort ett trรคd.
  • ๐Ÿ’ป Code Fรถrsedd: Pseudokod plus fungerar Python, C och C++ Programmen visar varje genomfart.

Vad รคr Tree Traversal?

I trรคddatastrukturen betyder traversering att besรถka noder pรฅ ett specifikt sรคtt. Det finns tvรฅ typer av traverseringar. Generellt sett รคr denna typ av traversering baserad pรฅ det binรคra trรคdet. Ett binรคrt trรคd innebรคr att varje nod kan ha maximalt 2 noder.

Ett binรคrt trรคd รคr en vรคlkรคnd datastruktur. Det finns ocksรฅ ett binรคrt sรถktrรคd (BST). Denna typ av traversering anvรคnds fรถr olika รคndamรฅl. Nivรฅordningsgenomgรฅngen, den anvรคnds fรถr att berรคkna djupet mellan tvรฅ noder. Det finns en annan typ av trรคd som kallas "AVL", dรคr det รคr nรถdvรคndigt att berรคkna hรถjden pรฅ en nod. Vi kan representera ett binรคrt trรคd i arrayen, men fรถr minnesoptimering kommer vi att anvรคnda struktur och pekare fรถr att referera till nรคsta nod.

Typer av trรคdpassering

Som vi diskuterade binรคra trรคd, nu diskuterar vi de enskilda typerna av traverseringar. Beroende pรฅ typerna finns det tvรฅ typer av traversering. Tidigare har vi nรคmnt nรถdvรคndigheten av nivรฅordning eller Breadth-First Traversal. Nu Depth-First Traversal som postorder anvรคnds fรถr radering av en nod (vi kommer att diskutera det senare), preorder anvรคnds fรถr att kopiera ett binรคrt trรคd, och "inorder" kommer att korsa trรคdet pรฅ ett icke-minskande sรคtt.

  • Bredd-fรถrsta genomgรฅng
  • Depth-First Traversal
  • Fรถrbestรคll genomgรฅng
  • Genomgรฅng efter order
  • Bestรคllningskorsning

Bredd-fรถrsta genomgรฅng

Det รคr ocksรฅ kรคnt som genomgรฅng av nivรฅordning. Lรฅt oss รถvervรคga fรถljande trรคd fรถr att demonstrera nivรฅordningsgenomgรฅngen.

Bredd-fรถrsta genomgรฅng

Sรฅ vi bรถrjar frรฅn rotnoden "1". Den kommer att markeras som nivรฅ 1. Sedan kommer algoritmen att gรฅ till alla barn i den aktuella noden. Vi besรถker nod 2 och 3 nu. De kommer att markeras som nivรฅ 2.

Efter det, eftersom vi har 2 noder pรฅ nivรฅ 2, kommer vi att besรถka deras barn ocksรฅ. Sรฅ vi kommer att besรถka 5,6,8,7 och markera dem som nivรฅ 3. Hรคr รคr en sak som inte nรคmns,

Nodens nivรฅ = fรถrรคldernodens nivรฅ + 1

Nivรฅ 1: 1

Nivรฅ 2: 2 3

Nivรฅ 3: 5 6 8 7

En liknande algoritm anvรคnds fรถr BFS (Utรถka fรถrsta sรถkningen).

Hรคr รคr pseudokoden fรถr genomgรฅng av nivรฅordning:

level_order(node)
Q โ†’ Queue()
Q.push(node)
while !Q.empty():
    current_node = Q.pop()
    print current_node.value
# Checking if the current node have any child or not
if current_node.left is not NULL:
    Q.push(current_node.left)
if current_node.right is not NULL:
    Q.push(current_node.right)

Inorder Traversal binรคrt trรคd

Lรฅt oss ta samma exempel som tidigare. I denna typ av traversering besรถker vi fรถrst det vรคnstra undertrรคdet, sedan roten och efter det det hรถgra undertrรคdet. Fรถr att gรถra det lรคttare att komma ihรฅg kan vi sรคga att det gรฅr som vรคnster-rot-hรถger.

Inorder Traversal binรคrt trรคd

Fรถr hela trรคdet, lรฅt oss sรคga att roten รคr 1. Nu fรถljer algoritmen:

  • Besรถk det vรคnstra undertrรคdet av nod 1.
  • Den nuvarande noden รคr 2 (eftersom det รคr det vรคnstra undertrรคdet av 1)

Inorder Traversal binรคrt trรคd

  • Besรถk det vรคnstra undertrรคdet av 2. Den aktuella noden kommer att vara 5 denna gรฅng.
  • Flytta till 5, det har inga barn, sรฅ nod 5 kommer att markeras som besรถkt. Den kommer att รฅtergรฅ till fรถrรคldranoden; vilket รคr 2.
  • Eftersom det vรคnstra undertrรคdet av 2 besรถks, kommer nu 2 att besรถkas ocksรฅ.
  • Ocuco-landskapet algoritm kommer att flytta den aktuella noden till hรถger undertrรคd av nod 2, vilket รคr nod 6. Efter att ha besรถkt nod 6. Den kommer att flytta till sin รถverordnade nod 2.
  • Nรคr nod 2 besรถks kommer vi nu att besรถka fรถrรคldern till 2; som รคr nod 1.
  • Efter det kommer vi att besรถka det hรถgra undertrรคdet.

Sรฅ den sista genomgรฅngen kommer att se ut sรฅ hรคr:

I ordning: 5 โ†’ 2 โ†’ 6 โ†’ 1 โ†’ 8 โ†’ 3 โ†’ 7

Hรคr รคr pseudokoden fรถr in-order-traversal:

InOrder(node):
  if node is not null:
    InOrder(node.left)
  print node.value
    InOrder(node.right)

Detta รคr den rekursiva algoritmen fรถr รถvergรฅngen av oordning. Fรถr Binรคrt sรถktrรคd (BST), Inorder-traversal ger den sorterade matrisen av vรคrden.

Traversering efter bestรคllning

I den hรคr genomgรฅngen kommer vi att korsa undertrรคdet lรคngst till vรคnster fรถrst, sedan undertrรคdet lรคngst till hรถger efter roten. Alla รถvergรฅngar kommer att vara i Post-Order. Lรฅt oss visa ett exempel:

Traversering efter bestรคllning

Hรคr fรถr rot = 1,

  • Vi gรฅr fรถrst till vรคnster undertrรคd. Sรฅ roten blir 2.
  • Dรฅ har 2 lรคmnat undertrรคdet, sรฅ vi gรฅr till nod 5. Nu รคr roten 5.
  • Det har inget vรคnster undertrรคd, det har inte heller nรฅgot hรถger undertrรคd. Sรฅ nu kommer vi att markera nod 5 som besรถkt och vi gรฅr till dess รถverordnade nod.

Traversering efter bestรคllning

  • Nu รคr roten 2 och dess vรคnstra undertrรคd รคr helt besรถkt. Vi kommer nu att flytta till dess hรถgra undertrรคd. Sรฅ roten blir 6.
  • Eftersom nod 6 inte har nรฅgot vรคnster och hรถger undertrรคd, kommer vi att markera nod 6 som besรถkt och flytta till dess รถverordnade nod 2.
  • Nu besรถks bรฅde vรคnster och hรถger undertrรคd fรถr nod 2. Det kommer ocksรฅ att markeras som besรถkt.
  • Vi flyttar till fรถrรคldern till nod 2, som รคr nod 1.
  • Det vรคnstra undertrรคdet besรถks fรถr rot 1. Pรฅ samma sรคtt kommer vi nu att besรถka det hรถgra undertrรคdet.

Traversering efter bestรคllning

Cirkeln markerad รคr det hรถgra undertrรคdet. Nu kommer vi att besรถka det hรถgra undertrรคdet som vi besรถkte det vรคnstra undertrรคdet. Efter det kommer vi att besรถka noden. Sรฅ den sista genomgรฅngen blir:

Postorder: 5 โ†’ 6 โ†’ 2 โ†’ 8 โ†’ 7 โ†’ 3 โ†’ 1

Hรคr รคr pseudokoden fรถr genomgรฅng av postorder:

PostOrder(node):
    if node is not null:
       PostOrder(node.left)
       PostOrder(node.right)
       print node.value

Fรถrbestรคllningstrafik

Fรถr fรถrbestรคllningsgenomgรฅngen kommer algoritmen att besรถka rotnoden fรถrst, efter det kommer den att flyttas till vรคnster respektive hรถger undertrรคd. Fรถr att underlรคtta fรถrstรฅelsen kan vi tรคnka pรฅ fรถrbestรคllning av genomgรฅngsbesรถk som rot โ†’ vรคnster-hรถger.

Fรถrbestรคllningstrafik

Sรฅ lรฅt oss vรคlja nod 1 som rot.

  • Enligt algoritmen kommer roten att upptรคckas fรถrst, sedan det vรคnstra och sedan det hรถgra undertrรคdet.
  • Sรฅ vi besรถker rot 1. Sedan flyttar vi till dess vรคnstra undertrรคd. Roten blir 2.
  • Vi besรถker nod 2 och gรฅr vidare till dess vรคnstra undertrรคd. Sรฅ roten blir 3.
  • Vi besรถker nod 3, sedan flyttar vi till dess modernod. Nu besรถks nod 2 och dess vรคnstra undertrรคd. Dags att besรถka rรคtt undertrรคd.
  • Vi flyttar till hรถger undertrรคd, roten blir 4. Vi besรถker 4. Eftersom 4 inte har nรฅgon underordnad nod, flyttar vi till dess fรถrรคlder.
  • Nu รคr roten 2 och den besรถks tillsammans med dess vรคnstra och hรถgra undertrรคd. Sรฅ vi flyttar till dess รถverordnade nod. Nu blir root 1.
  • Pรฅ samma sรคtt kommer vi att besรถka det hรถgra undertrรคdet.

Fรถrbestรคllning: 1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 5 โ†’ 6 โ†’ 7

Hรคr รคr pseudokoden fรถr fรถrbestรคllningstraversering:

PreOrder(node):
   if node is not null:
     print node.value
         PreOrder(node.left)
         PreOrder(node.right)

Genomfรถrande i Python

class Node:
    def __init__(self, item):
    self.left = None
self.right = None
self.val = item
# creating a tree data structure
def inorder(root):
#checking if the root is null or not
if root:
    inorder(root.left)
# recursively calling left subtree
print(str(root.val) + " ", end = '')
inorder(root.right)
# recursively calling right subtree
def postorder(root):
    if root:
    postorder(root.left)
postorder(root.right)
print(str(root.val) + " ", end = '')
def preorder(root):
    if root:
    print(str(root.val) + " ", end = '')
preorder(root.left)
preorder(root.right)
def levelOrder(root):
    queue = list()
queue.append(root)
while len(queue) >
0:
    current = queue[0]
queue = queue[1: ]
print(str(current.val) + " ", end = "")
if current.left:
    queue.append(current.left)
if current.right:
   queue.append(current.right)
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
print("\nLevelOrder traversal:\t", end = " ")
levelOrder(root)
print("\nInorder traversal:\t", end = " ")
inorder(root)
print("\nPreorder traversal:\t", end = " ")
preorder(root)
print("\nPostorder traversal:\t", end = " ")
postorder(root)

Produktion:

LevelOrder traversal:  1 2 3 4 5 6 7
Inorder traversal:     4 2 5 1 6 3 7
Preorder traversal:    1 2 4 5 3 6 7
Postorder traversal:   4 5 2 6 7 3 1

Implementering i C

#include <stdio.h>
#include <stdlib.h>
struct node {
   int value;
   struct node* left;
   struct node* right;
};
// Inorder traversal
void InOrder(struct node* root) {
   if (root == NULL) return;
   InOrder(root->left);
   printf("%d ", root->value);
   InOrder(root->right);
}
// PreOrder traversal
void PreOrder(struct node* root) {
  if (root == NULL) return;
  printf("%d ", root->value);
  PreOrder(root->left);
  PreOrder(root->right);
}
// PostOrder traversal
void PostOrder(struct node* root) {
  if (root == NULL) return;
  PostOrder(root->left);
  PostOrder(root->right);
  printf("%d ", root->value);
}
// Create a new Node
struct node* createNode(int value) {
  struct node* newNode = malloc(sizeof(struct node));
  newNode->value = value;
  newNode->left = NULL;
  newNode->right = NULL;
  return newNode;
}
int main() {
  struct node* root = createNode(1);
  root->left = createNode(2);
  root->right = createNode(3);
  root->left->left = createNode(4);
  root->left->right = createNode(5);
  root->right->left = createNode(6);
  root->right->right = createNode(7);
  printf("Inorder traversal:\t");
  InOrder(root);
  printf("\PreOrder traversal:\t");
  PreOrder(root);
  printf("\nPostOrder traversal:\t");
  PostOrder(root);
}

Produktion:

Inorder traversal: 4 2 5 1 6 3 7
Preorder traversal: 1 2 4 5 3 6 7
Postorder traversal: 4 5 2 6 7 3 1

Infรถrande av C++ (Anvรคnder std::queue fรถr nivรฅordning)

#include <stdio.h>
#include <stdlib.h>
#include<queue>
typedef struct node {
  int value;
  struct node* left;
  struct node* right;
}node;
// Inorder traversal
void InOrder(struct node* root) {
  if (root == NULL) return;
  InOrder(root->left);
  printf("%d ", root->value);
  InOrder(root->right);
}
// PreOrder traversal
void PreOrder(struct node* root) {
  if (root == NULL) return;
  printf("%d ", root->value);
  PreOrder(root->left);
  PreOrder(root->right);
}
// PostOrder traversal
void PostOrder(struct node* root) {
  if (root == NULL) return;
  PostOrder(root->left);
  PostOrder(root->right);
  printf("%d ", root->value);
}
void LevelOrder(struct node* root){
   std::queue<struct node*> Q;
   Q.push(root);
   while(!Q.empty()){
   struct node* current = Q.front();
   Q.pop();
   printf("%d ",current->value);
 if(current->left)
   Q.push(current->left);
 if(current->right)
   Q.push(current->right);
  }
}
// Create a new Node
struct node* createNode(int value) {
  struct node* newNode = new node();
  newNode->value = value;
  newNode->left = NULL;
  newNode->right = NULL;
  return newNode;
}
int main() {
  struct node* root = createNode(1);
  root->left = createNode(2);
  root->right = createNode(3);
  root->left->left = createNode(4);
  root->left->right = createNode(5);
  root->right->left = createNode(6);
  root->right->right = createNode(7);
  printf("Level Order traversal:\t");
  LevelOrder(root);
  printf("\nInorder traversal:\t");
  InOrder(root);
  printf("\nPreOrder traversal:\t");
  PreOrder(root);
  printf("\nPostOrder traversal:\t");
  PostOrder(root);
}
LevelOrder traversal:  1 2 3 4 5 6 7
Inorder traversal:     4 2 5 1 6 3 7
Preorder traversal:    1 2 4 5 3 6 7
Postorder traversal:   4 5 2 6 7 3 1

Vanliga frรฅgor

Djupfรถrst-genomgรฅngen gรฅr djupt lรคngs en gren innan den gรฅr tillbakatrackung, med hjรคlp av rekursion eller en stack; inorder, preorder och postorder รคr dess former. Bredd-fรถrst-traversal besรถker noder nivรฅ fรถr nivรฅ med hjรคlp av en kรถ. DFS utforskar djup; BFS utforskar bredd.

Ja. Du kan รฅterskapa ett unikt binรคrt trรคd frรฅn dess inorder-traversal kombinerat med antingen dess preorder- eller postorder-traversal. Inorder visar vรคnster-hรถger-position, medan preorder eller postorder identifierar roten, sรฅ tillsammans fixar de varje nod.

Varje trรคdgenomgรฅng besรถker varje nod exakt en gรฅng, sรฅ tidskomplexiteten รคr O(n) fรถr n noder. Rymdkomplexiteten รคr O(h), dรคr h รคr trรคdhรถjden, pรฅ grund av den rekursion eller kรถ som anvรคnds.

AI-handledare kan animera varje genomgรฅng, markera den aktuella noden och visa hur utdataordningen bildas. De kan ocksรฅ frรฅga dig och fรถrklara varfรถr inorder pรฅ en BST returnerar sorterade vรคrden, vilket gรถr konceptet lรคttare att fรถrstรฅ.

Ja. AI-kodningsassistenter kan generera kod fรถr inorder, preorder, postorder och level-order traversal i sprรฅk som Python, C, C++och JavaDu bรถr fortfarande testa utdata fรถr att bekrรคfta att genomgรฅngsordningen รคr korrekt.

Sammanfatta detta inlรคgg med: