При дадено двоично дърво и препратка към коренния възел на дървото, трансформирайте листовите възли на дървото в двойно свързан списък в последователност по ред.
Този проблем може да бъде разделен на части — Намерете листовите възли на двоично дърво и даден набор от елементи, формирайте двойно свързан списък, като ги използвате.
Намерете листовите възли на двоично дърво -
За да обходим двоично дърво, можем да обходим дървото с помощта на алгоритми за обхождане в предварителна поръчка, по ред или след поръчка.
Обхождане на предварителна поръчка — ROOT -› НАЛЯВО -› НАДЯСНО
Обхождане по ред — НАЛЯВО -› КОРЕН -› НАДЯСНО
Traversal след поръчка — НАЛЯВО -› ДЯСНО -› КОРЕН
Решението на текущия проблем използва Inorder Traversal.
Алгоритъмът за Inorder Traversal е както следва:
1) Въведете основния възел.
2) Ако основният (текущият) възел няма ляво или дясно дете, тогава това е листов възел, в противен случай отидете на стъпка (3)
3) Ако коренният възел е NULL, тогава върнете else goto стъпка (4).
4) Прочетете коренния възел на лявото поддърво и преминете към стъпка (1).
5) Отпечатайте стойността на текущия възел.
6) Прочетете коренния възел на дясното поддърво и преминете към стъпка (2).
Даден е набор от елементи, формирайте двойно свързан списък, използвайки ги -
Структурата на данните за възела на двойно свързан списък е -
Двойно свързан списък е различен от единично свързан списък, тъй като в двойно свързан списък можем да преминем по двата начина, отляво надясно и отдясно наляво, докато в единично свързан списък можем да преминем само в една посока, от ляво на дясно или от дясно на ляво.
Можем да формираме двойно свързан списък от дадените елементи чрез свързани възли един с друг чрез итерация до последния възел и свързване на текущия възел с последния възел на текущия свързан списък.
Даденият по-долу код е на език за програмиране C.
#include<stdio.h> #include<stdlib.h> struct node{ struct node *left; int data; struct node *right; }; struct node *head = NULL; void leavesToDll(struct node *leaf){ struct node *first; if(head == NULL){ head = leaf; } else{ first = head; while(first -> right != NULL){ first = first -> right; } first -> right = leaf; leaf -> left = first; } } void inorderTraversal(struct node *root){ if(root -> left == NULL && root -> right == NULL){ leavesToDll(root); } else if(root == NULL){ return; } else{ inorderTraversal(root -> left); inorderTraversal(root -> right); } } struct node *newNode(int data){ struct node *n = (struct node *)malloc(sizeof(struct node *)); n -> data = data; n -> left = NULL; n -> right = NULL; return n; } void main(){ struct node *n = newNode(1); n -> left = newNode(2); n -> left -> left = newNode(4); n -> left -> right = newNode(5); n -> right = newNode(3); n -> right -> left = newNode(6); n -> right -> right = newNode(7); inorderTraversal(n); while(head -> right != NULL){ printf("%d\n", head -> data); head = head -> right; } printf("%d\n", head -> data); }
Първоначално публикувано на http://asquero.com.