차례
문제 정책
"제한된 추가 공간으로 두 개의 BST 병합"문제는 두 개의 이진 검색 트리(BST) 두 트리의 요소를 정렬 된 순서로 인쇄해야합니다. 이는 요소가 단일 BST에서 온 것처럼 보이는 순서입니다.
예
입력
산출
4 5 6 7 9 13
설명 : 두 입력 트리를 병합하여 형성된 새 트리가 이미지에 표시됩니다. 결과 트리의 inorder traversal은 출력을 제공합니다.
제한된 추가 공간으로 두 BST를 병합하는 방법
"제한된 추가 공간으로 두 BST 병합"문제는 병합 된 트리의 순회 순회를 인쇄하도록 요청합니다. 병합 된 트리는 주어진 두 트리를 병합하여 형성됩니다. 따라서 우리는 주어진 나무를 병합하려고 시도 할 것입니다. 그러나 나무를 병합하려면 많은 오버 헤드가 필요합니다. 직접 병합하는 대신 다른 방법을 생각할 수 있습니다. 주어진 트리의 노드 값을 정렬 된 형태로 인쇄하기 만하면됩니다.
이 문제를 해결하기 위해 두 트리에서 동시에 이진 검색 트리의 반복적 인 순서 순회를 실행하려고합니다. 실행하면 가능합니다. 순서 순회. 그리고 inorder traversal에서 두 노드의 값을 비교하십시오. 그런 다음 둘 중 더 작은 노드를 인쇄하고 스택 (반복적 인 순서 순회 중에 사용되는 스택)에 더 큰 노드를 푸시합니다. 트리 중 하나에 대한 작업을 마칠 때마다 노드가 남아있는 상태에서 트리를 순회하는 순회를 실행합니다.
암호
제한된 추가 공간으로 두 BST를 병합하는 C ++ 코드
#include <bits/stdc++.h> using namespace std; struct node { int data; node *left; node *right; }; // returns a new node with supplied data node* create(int data) { node *temp = new node; temp->data = data; temp->left = temp->right = NULL; return temp; } void inorder(node *root) { if(root){ inorder(root->left); cout<<root->data<<" "; inorder(root->right); } } void merge(node *root1, node *root2) { stack<node*> s1;node* cur1 = root1; stack<node*> s2;node* cur2 = root2; //if first tree is empty, print second tree if(!root1){ inorder(root2); return; } // if second tree is empty, print first tree if(!root2){ inorder(root2); return; } // print the nodes which are not yet visited or visited but not printed while(cur1 != NULL || !s1.empty() || cur2 != NULL || !s2.empty()) { // iterative inorder if(cur1 != NULL || cur2 != NULL) { // Reach the leftmost node of both BSTs and push ancestors of // leftmost nodes to stack s1 and s2 respectively if(cur1 != NULL) { s1.push(cur1); cur1 = cur1->left; } if (cur2 != NULL) { s2.push(cur2); cur2 = cur2->left; } } else { // if anyone of the tree's current node becomes Null // then we need to check if stack is empty if(s1.empty()) { while(!s2.empty()) { cur2 = s2.top();s2.pop(); cur2->left = NULL; inorder(cur2); } return; } if(s2.empty()) { while(!s1.empty()) { cur1 = s1.top();s1.pop(); cur1->left = NULL; inorder(cur1); } return; } // compare elements at the top of both stacks cur1 = s1.top();s1.pop(); cur2 = s2.top();s2.pop(); // print the smaller of the two and push the larger element into the corresponding stack if(cur1->data < cur2->data) { cout<<cur1->data<<" "; cur1 = cur1->right; s2.push(cur2); cur2 = NULL; } else { cout<<cur2->data<<" "; cur2 = cur2->right; s1.push(cur1); cur1 = NULL; } } } } int main() { node *root1 = NULL, *root2 = NULL; //first tree root1 = create(5); root1->left = create(4); root1->right = create(13); //second tree root2 = create(7); root2->left = create(6); root2->right = create(9); // Print sorted nodes of both trees merge(root1, root2); return 0; }
4 5 6 7 9 13
제한된 추가 공간으로 두 BST를 병합하는 Java 코드
import java.util.*; import java.lang.*; import java.io.*; class node{ int data; node left; node right; } class Tree{ static node root; static int count; static node create(int data){ node tmp = new node(); tmp.data = data; tmp.left = null; tmp.right = null; return tmp; } static void inorder(node root) { if(root != null){ inorder(root.left); System.out.print(root.data+" "); inorder(root.right); } } static void merge(node root1, node root2) { Stack<node> s1 = new Stack<>();node cur1 = root1; Stack<node> s2 = new Stack<>();node cur2 = root2; //if first tree is empty, print second tree if(root1 == null){ inorder(root2); return; } // if second tree is empty, print first tree if(root2 == null){ inorder(root1); return; } // print the nodes which are not yet visited or visited but not printed while(cur1 != null || s1.empty() == false || cur2 != null || s2.empty() == false) { if(cur1 != null || cur2 != null) { // Reach the leftmost node of both BSTs and push ancestors of // leftmost nodes to stack s1 and s2 respectively if(cur1 != null) { s1.push(cur1); cur1 = cur1.left; } if (cur2 != null) { s2.push(cur2); cur2 = cur2.left; } } else { // if anyone of the tree's current node becomes Null // then we need to check if stack is empty if(s1.empty() == true) { while (s2.empty() == false) { cur2 = s2.pop(); cur2.left = null; inorder(cur2); } return ; } if(s2.empty() == true) { while (s1.empty() == false) { cur1 = s1.pop(); cur1.left = null; inorder(cur1); } return ; } // compare elements at the top of both stacks cur1 = s1.pop(); cur2 = s2.pop(); // print the smaller of the two and push the larger element into the corresponding stack if (cur1.data < cur2.data) { System.out.print(cur1.data+" "); cur1 = cur1.right; s2.push(cur2); cur2 = null; } else { System.out.print(cur2.data+" "); cur2 = cur2.right; s1.push(cur1); cur1 = null; } } } } public static void main(String[] args) { node root1 = null; node root2 = null; //first tree root1 = create(5); root1.left = create(4); root1.right = create(13); //second tree root2 = create(7); root2.left = create(6); root2.right = create(9); // Print sorted nodes of both trees merge(root1, root2); } }
4 5 6 7 9 13
복잡성 분석
시간 복잡성
O (N + M), 두 트리를 동시에 순회하기 때문입니다. inorder traversal 동안 우리는 두 트리의 노드를 살펴 보았으므로 선형 시간 복잡성이 발생했습니다.
공간 복잡성
O (N + M), 보다 공식적으로 공간 복잡성은 두 나무의 높이의 합이 될 것입니다. 그러나 최악의 경우 입력은 기울어 진 트리 일 수 있으며이 경우 높이는 트리의 노드 수와 동일합니다.