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++.

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.
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.
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)
- 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:
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.
- 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.
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.
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






