Tregjennomgang (Inorder, Preorder, Postorder)

โšก Smart oppsummering

Tretraverseringer besรธker hver node i et binรฆrt tre i en definert rekkefรธlge. Denne ressursen forklarer bredde-fรธrst (nivรฅ-rekkefรธlge) og de tre dybde-fรธrst-metodene โ€“ inorder, preorder og postorder โ€“ med trinnvise eksempler, pseudokode og komplette implementeringer i Python, C og C++.

  • ???? To kategorier: Traverseringer er delt inn i bredde fรธrst (nivรฅrekkefรธlge) og dybde fรธrst (i rekkefรธlge, forhรฅndsrekkefรธlge, etterrekkefรธlge).
  • ร‚ยฌ i ... I rekkefรธlge: Besรธker venstre undertre, rot, deretter hรธyre undertre; pรฅ en BST returnerer den verdier i sortert rekkefรธlge.
  • ๐Ÿ” Forhรฅndsbestille: Besรธker roten fรธrst, deretter venstre og hรธyre undertrรฆr; nyttig for รฅ kopiere et tre.
  • ๐Ÿ”š Postordre: Besรธker venstre og hรธyre undertrรฆr fรธr roten; nyttig for รฅ slette et tre.
  • ๐Ÿ’ป Code Sรธrget for: Pseudokode pluss fungerer Python, C og C++ Programmer demonstrerer hver gjennomgang.

Hva er Tree Traversal?

I datastrukturen for treet betyr traversering รฅ besรธke noder pรฅ en spesifikk mรฅte. Det finnes to typer traverseringer. Vanligvis er denne typen traversering basert pรฅ det binรฆre treet. Et binรฆrt tre betyr at hver node kan ha maksimalt 2 noder.

Et binรฆrt tre er en velkjent datastruktur. Det er ogsรฅ et binรฆrt sรธketre (BST). Denne typen traversering brukes til ulike formรฅl. Nivรฅrekkefรธlgen, den brukes til รฅ beregne dybden mellom to noder. Det er en annen type tre kalt "AVL", der det er nรธdvendig รฅ beregne hรธyden pรฅ en node. Vi kan representere et binรฆrt tre i matrisen, men for minneoptimalisering vil vi bruke struktur og peker for รฅ referere til neste node.

Typer trekryssing

Som vi diskuterte binรฆre trรฆr, nรฅ diskuterer vi de enkelte typene traverseringer. Avhengig av typene er det to typer traversering. Tidligere har vi nevnt nรธdvendigheten av nivรฅrekkefรธlge eller Breadth-First Traversal. Nรฅ Dybde-fรธrste traversering som postordre brukes for sletting av en node (vi vil diskutere det senere), preorder brukes for รฅ kopiere et binรฆrt tre, og "inorder" vil krysse treet pรฅ en ikke-minskende mรฅte.

  • Breadth-First Traversal
  • Dybde-fรธrste traversering
  • Forhรฅndsbestill traversering
  • Traversering etter bestilling
  • Traversering i rekkefรธlge

Breadth-First Traversal

Det er ogsรฅ kjent som nivรฅrekkefรธlgen. La oss vurdere fรธlgende tre for รฅ demonstrere nivรฅrekkefรธlgen.

Breadth-First Traversal

Sรฅ vi starter fra rotnoden "1". Den vil bli merket som nivรฅ 1. Deretter vil algoritmen gรฅ til alle barna til gjeldende node. Vi besรธker node 2 og 3 nรฅ. De vil bli merket som nivรฅ 2.

Etter det, siden vi har 2 noder pรฅ nivรฅ 2, besรธker vi barna deres ogsรฅ. Sรฅ vi besรธker 5,6,8,7 og markerer dem som nivรฅ 3. Her er en ting som ikke nevnes,

Nivรฅ av node = overordnet nodes nivรฅ + 1

Nivรฅ 1: 1

Nivรฅ 2: 2 3

Nivรฅ 3: 5 6 8 7

En lignende algoritme brukes for BFS (Bredde-fรธrst-sรธk).

Her er pseudokoden for gjennomgang av nivรฅordre:

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รฆrtre

La oss ta det samme eksempelet som fรธr. I denne typen traversering besรธker vi fรธrst det venstre undertreet, deretter roten, og deretter det hรธyre undertreet. For รฅ lette รฅ huske kan vi si at rekkefรธlgen gรฅr som venstre-rot-hรธyre.

Inorder Traversal binรฆrtre

For hele treet, la oss si at roten er 1. Nรฅ vil algoritmen fรธlge:

  • Besรธk det venstre undertreet til node 1.
  • Den nรฅvรฆrende noden er 2 (ettersom det er venstre undertre av 1)

Inorder Traversal binรฆrtre

  • Gรฅ til venstre undertre av 2. Gjeldende node vil vรฆre 5 denne gangen.
  • Flytter til 5, den har ingen barn, sรฅ node 5 vil bli merket som besรธkt. Den vil gรฅ tilbake til overordnet node; som er 2.
  • Ettersom venstre undertre av 2 er besรธkt, vil nรฅ 2 ogsรฅ bli besรธkt.
  • Ocuco algoritme vil flytte gjeldende node til hรธyre undertre av node 2, som er node 6. Etter รฅ ha besรธkt node 6. Den vil flytte til sin overordnede node 2.
  • Ettersom node 2 er besรธkt, vil vi nรฅ besรธke forelderen til 2; som er node 1.
  • Etter det besรธker vi det hรธyre undertreet.

Sรฅ den endelige gjennomgangen vil se slik ut:

I rekkefรธlge: 5 โ†’ 2 โ†’ 6 โ†’ 1 โ†’ 8 โ†’ 3 โ†’ 7

Her er pseudokoden for in-order traversering:

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

Dette er den rekursive algoritmen for gjennomgang av uorden. For Binรฆrt sรธketre (BST), Inorder-gjennomgang gir den sorterte matrisen av verdier.

Traversering etter bestilling

I denne traverseringen vil vi krysse undertreet lengst til venstre fรธrst, deretter undertreet lengst til hรธyre etter roten. Alle gjennomgangene vil vรฆre i etterbestilling. La oss demonstrere et eksempel:

Traversering etter bestilling

Her for rot = 1,

  • Vi gรฅr fรธrst til venstre undertre. Sรฅ roten blir 2.
  • Da har 2 forlatt undertreet, sรฅ vi gรฅr til node 5. Nรฅ er roten 5.
  • Det har ikke noe venstre undertre, det har heller ikke noe hรธyre undertre. Sรฅ nรฅ vil vi merke node 5 som besรธkt, og vi gรฅr til dens overordnede node.

Traversering etter bestilling

  • Nรฅ er roten 2 og venstre undertre er fullstendig besรธkt. Vi vil nรฅ flytte til hรธyre undertre. Sรฅ roten blir 6.
  • Siden node 6 ikke har noe venstre og hรธyre undertre, vil vi merke node 6 som besรธkt og flytte til overordnet node 2.
  • Nรฅ blir bรฅde venstre og hรธyre undertre besรธkt for node 2. Det vil ogsรฅ bli merket som besรธkt.
  • Vi gรฅr til overordnet til node 2, som er node 1.
  • Det venstre undertreet besรธkes for rot 1. Pรฅ samme mรฅte besรธker vi det hรธyre undertreet.

Traversering etter bestilling

Sirkelen merket er det hรธyre undertreet. Nรฅ skal vi besรธke det hรธyre undertreet slik vi besรธkte det venstre undertreet. Etter det vil vi besรธke noden. Sรฅ den siste gjennomgangen blir:

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

Her er pseudokoden for etterbestilling:

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

Forhรฅndsbestill Traversal

For forhรฅndsbestillingsgjennomgangen vil algoritmen besรธke rotnoden fรธrst, etter det vil den flytte til henholdsvis venstre og hรธyre undertre. For รฅ lette forstรฅelsen, kan vi tenke pรฅ forhรฅndsbestill traversale besรธk som rot โ†’ venstre-hรธyre.

Forhรฅndsbestill Traversal

Sรฅ la oss velge node 1 som roten.

  • I henhold til algoritmen vil roten bli oppdaget fรธrst, deretter det venstre og deretter det hรธyre undertreet.
  • Sรฅ vi besรธker rot 1. Deretter flytter vi til venstre undertre. Roten blir 2.
  • Vi besรธker node 2 og gรฅr til dens venstre undertre. Dermed blir roten 3.
  • Vi besรธker node 3, sรฅ flytter vi til dens overordnede node. Nรฅ er node 2 og dets venstre undertre besรธkt. Pรฅ tide รฅ besรธke det riktige undertreet.
  • Vi flytter til hรธyre undertre, roten blir 4. Vi besรธker 4. Siden 4 ikke har noen underordnet node, flytter vi til dens overordnede node.
  • Nรฅ er root 2 og den besรธkes sammen med venstre og hรธyre undertre. Sรฅ vi gรฅr til overordnet node. Nรฅ blir root 1.
  • Pรฅ samme mรฅte besรธker vi det hรธyre undertreet.

Forhรฅndsbestilling: 1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 5 โ†’ 6 โ†’ 7

Her er pseudokoden for forhรฅndsbestillingsgjennomgang:

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

Gjennomfรธring 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)

Utgang:

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);
}

Produksjon:

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 av C++ (Bruker std::queue for nivรฅrekkefรธlge)

#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

Spรธrsmรฅl og svar

Dybdefรธrst traversering gรฅr dypt langs รฉn gren fรธr den gรฅr tilbaketracking, ved hjelp av rekursjon eller en stabel; inorder, preorder og postorder er formene. Bredde-fรธrst-traversal besรธker noder nivรฅ for nivรฅ ved hjelp av en kรธ. DFS utforsker dybde; BFS utforsker bredde.

Ja. Du kan gjenoppbygge et unikt binรฆrtre fra dets inorder-traversering kombinert med enten dets preorder- eller postorder-traversering. Inorder viser venstre-hรธyre-posisjon, mens preorder eller postorder identifiserer roten, slik at de sammen fikser hver node.

Hver tregjennomgang besรธker hver node nรธyaktig รฉn gang, sรฅ tidskompleksiteten er O(n) for n noder. Romkompleksiteten er O(h), hvor h er trehรธyden, pรฅ grunn av rekursjonen eller kรธen som brukes.

AI-veiledere kan animere hver traversering, markere gjeldende node og vise hvordan utdatarekkefรธlgen dannes. De kan ogsรฅ stille deg spรธrsmรฅl og forklare hvorfor inorder pรฅ en BST returnerer sorterte verdier, noe som gjรธr konseptet lettere รฅ forstรฅ.

Ja. AI-kodingsassistenter kan generere kode for inorder, preorder, postorder og level-order traversal i sprรฅk som Python, C, C++og JavaDu bรธr fortsatt teste utdataene for รฅ bekrefte at gjennomlรธpsrekkefรธlgen er riktig.

Oppsummer dette innlegget med: