İkili Axtarış Ağacı verildiyi üçün, BST-ni İkili'yə çevirmək üçün bir alqoritm yazın Ağac bütün böyük düymələrin cəmi hər düyməyə əlavə ediləcəkdir.
Mündəricat
misal
Input
Buraxılış
Ön sifariş: 81 87 88 54 69 34
Sadəlövh yanaşma
Fikir çox sadədir, keçmək bütün qovşaqlar bir-bir, hər bir qovşaq üçün yenidən bütün ağacdan keçir və ondan böyük qovşaqların cəmini tapın. Cəmi bir massivdə saxlayın və hesablamadan sonra bütün qovşaqlar üçün cəmi, qovşaqları uyğun cəmlərlə artırın. Bu yanaşma hər hansı bir ümumi ikili ağac üçün tətbiq olunur və xüsusilə BST üçün deyil.
- Verilən BST-i sifariş şəklində keçin.
- Hər bir qovşaq üçün yenidən nizamlı şəkildə ağacdan keçin və cari qovşaqdan böyük olan bütün qovşaqların cəmini tapın.
- Cəmi bir sıra və ya siyahıda saxlayın.
- Bütün qovşaqlardan keçdikdən sonra yenidən nizamlı şəkildə ağacdan keçin və sıra və ya siyahıdakı müvafiq cəmi ilə hər bir qovluğu artırın.
Zaman Mürəkkəbliyi = O (n)2)
Kosmik Mürəkkəblik = O (h)
burada n ağacdakı qovşaq sayıdır.
Bir BST-ni ikili bir ağaca çevirmək üçün JAVA kodu
import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; public class ConvertABSTToABinaryTreeSuchThatSumOfAllGreaterKeysIsAddedToEveryKey { // class representing the node of a binary tree static class Node { int data; Node left, right; public Node(int data) { this.data = data; } } // function to print the pre-order traversal of a binary tree private static void preOrder(Node root) { if (root != null) { System.out.print(root.data + " "); preOrder(root.left); preOrder(root.right); } } private static int findSum(Node root, int value) { // if root is null, sum is 0 if (root == null) { return 0; } // initialize sum as 0 int sum = 0; // traverse the tree and find the sum of all the values greater than value Queue<Node> queue = new LinkedList<>(); queue.add(root); while (!queue.isEmpty()) { Node curr = queue.poll(); if (curr.data > value) { sum += curr.data; } if (curr.left != null) queue.add(curr.left); if (curr.right != null) queue.add(curr.right); } // return sum return sum; } private static void formSumList(Node root, Node curr, ArrayList<Integer> sumList) { // traverse the tree in in-order form and for each node // calculate the sum of elements greater than it if (curr != null) { formSumList(root, curr.left, sumList); // Check for all the nodes to find the sum int sum = findSum(root, curr.data); sumList.add(sum); formSumList(root, curr.right, sumList); } } private static void convertToGreaterSumTree(Node root, ArrayList<Integer> sumList) { // traverse the tree in in-order form and for each node // increment its value by sum if (root != null) { convertToGreaterSumTree(root.left, sumList); // increment this value root.data += sumList.get(0); sumList.remove(0); convertToGreaterSumTree(root.right, sumList); } } public static void main(String[] args) { // Example Tree Node root = new Node(12); root.left = new Node(6); root.right = new Node(20); root.left.left = new Node(1); root.right.left = new Node(15); root.right.right = new Node(34); ArrayList<Integer> sumList = new ArrayList<>(); formSumList(root, root, sumList); convertToGreaterSumTree(root, sumList); preOrder(root); System.out.println(); } }
81 87 88 54 69 34
Bir BST-ni ikili bir ağaca çevirmək üçün C ++ kodu
#include <iostream> #include<vector> #include<queue> using namespace std; // class representing node of a binary tree class Node { public: int data; Node *left; Node *right; Node(int d) { data = d; left = right = NULL; } }; // function to print the preorder traversal of a binary tree void preOrder(Node *root) { if (root != NULL) { cout<<root->data<<" "; preOrder(root->left); preOrder(root->right); } } int findSum(Node *root, int value) { // if root is null, sum is 0 if (root == NULL) { return 0; } // initialize sum as 0 int sum = 0; // traverse the tree and find the sum of all the values greater than value queue<Node*> q; q.push(root); while (!q.empty()) { Node *curr = q.front(); q.pop(); if (curr->data > value) { sum += curr->data; } if (curr->left != NULL) { q.push(curr->left); } if (curr->right != NULL) { q.push(curr->right); } } // return sum return sum; } void formSumList(Node *root, Node *curr, vector<int> &sumList) { // traverse the tree in in-order form and for each node // calculate the sum of elements greater than it if (curr != NULL) { formSumList(root, curr->left, sumList); // Check for all the nodes to find the sum int sum = findSum(root, curr->data); sumList.push_back(sum); formSumList(root, curr->right, sumList); } } void convertToGreaterSumTree(Node *root, vector<int> &sumList) { // traverse the tree in in-order form and for each node // replace its value with the corresponding sum if (root != NULL) { convertToGreaterSumTree(root->left, sumList); // change this value root->data += sumList[0]; sumList.erase(sumList.begin()); convertToGreaterSumTree(root->right, sumList); } } int main() { // Example Tree Node *root = new Node(12); root->left = new Node(6); root->right = new Node(20); root->left->left = new Node(1); root->right->left = new Node(15); root->right->right = new Node(34); vector<int> sumList; formSumList(root, root, sumList); convertToGreaterSumTree(root, sumList); preOrder(root); cout<<endl; return 0; }
81 87 88 54 69 34
Optimal yanaşma
Yuxarıdakı yanaşma bir BST üçün optimallaşdırıla bilər, çünki bir BST məlumatları çox dəqiq bir şəkildə saxlayır.
BST-ni tərs qaydada, yəni sağ-> kök-> sol formada keçin. Bu şəkildə qovşaqları azalan qaydada keçəcəyik və hər hansı bir qovşaqı ziyarət etməzdən əvvəl ondan daha çox qovşaqları ziyarət edəcəyik, bu səbəbdən yalnız bir keçiddə bir qovşaqdan daha böyük olan bütün qovşaqların cəmini tapa bilərik və bu keçid artımı zamanı hər bir qovşaq ondan böyük qovşaqların cəmi ilə.
- Dəyişən bir cəmi 0 olaraq başlatın, referansla ötürülür və ya qlobal olaraq təyin edilir.
- BST-i tərs qaydada düzəldin, beləliklə məlumatları azalan qaydada əldə edəcəyik.
- Keçdiyimiz hər bir düyün üçün dəyərini cəmlə artırın və cəmi düyünün orijinal dəyərinə görə artırın (yenilənmədən əvvəl).
Zaman Mürəkkəbliyi = O (n)
Kosmik Mürəkkəblik = O (h)
burada n - verilən BST-də qovşaqların ümumi sayı.
Bir BST-ni ikili bir ağaca çevirmək üçün JAVA kodu
public class ConvertABSTToABinaryTreeSuchThatSumOfAllGreaterKeysIsAddedToEveryKey { // class representing node of a binary tree static class Node { int data; Node left, right; public Node(int data) { this.data = data; } } // function to print the pre-order traversal of a binary tree private static void preOrder(Node root) { if (root != null) { System.out.print(root.data + " "); preOrder(root.left); preOrder(root.right); } } // sum defined globally and initialized as 0 private static int sum = 0; private static void convertToGreaterSumTree(Node root) { // traverse the tree in reverse in-order form if (root != null) { convertToGreaterSumTree(root.right); // update the sum and increment the node's value int prevValue = root.data; root.data += sum; sum += prevValue; convertToGreaterSumTree(root.left); } } public static void main(String[] args) { // Example Tree Node root = new Node(12); root.left = new Node(6); root.right = new Node(20); root.left.left = new Node(1); root.right.left = new Node(15); root.right.right = new Node(34); convertToGreaterSumTree(root); preOrder(root); System.out.println(); } }
81 87 88 54 69 34
Bir BST-ni ikili bir ağaca çevirmək üçün C ++ kodu
#include <iostream> #include<vector> #include<queue> using namespace std; // sum defined globally and initialized as 0 int sum = 0; // class representing node of a binary tree class Node { public: int data; Node *left; Node *right; Node(int d) { data = d; left = right = NULL; } }; // function to print the preorder traversal of a binary tree void preOrder(Node *root) { if (root != NULL) { cout<<root->data<<" "; preOrder(root->left); preOrder(root->right); } } void convertToGreaterSumTree(Node *root) { // traverse the tree in reverse in-order form if (root != NULL) { convertToGreaterSumTree(root->right); // update the sum and the node's value int prevValue = root->data; root->data += sum; sum += prevValue; convertToGreaterSumTree(root->left); } } int main() { // Example Tree Node *root = new Node(12); root->left = new Node(6); root->right = new Node(20); root->left->left = new Node(1); root->right->left = new Node(15); root->right->right = new Node(34); convertToGreaterSumTree(root); preOrder(root); cout<<endl; return 0; }
81 87 88 54 69 34