두 갈래 트리 시리즈 - 두 갈래 검색 트리 - 선형 시간 내에 질서 체인 테이블을 BST로 전환
23542 단어 두 갈래 나무
인용문
이 문서는 Google의 제목입니다.
how to merge two binary search tree into balanced binary search tree. how to merge two binary search tree into balanced binary search tree.. Let there be m elements in first tree and n elements in the other tree. Your merge function should take O(m+n) time and do it in place.
http://www.careercup.com/question?id=5261732222074880
선형 시간 내에 완성해야 하고 inplace를 요구하면 BST를 Double linked list로 전환할 생각을 하기 어렵지 않다.
그리고 두 개의dllmerge를그러나 선형 시간의 복잡도가 있는 알고리즘이 dll을 BST로 바꿉니까?
다음은 본고에서 기술하고자 하는 내용입니다. 알고리즘은
http://www.geeksforgeeks.org/in-place-conversion-of-sorted-dll-to-balanced-bst/
정렬된 Double linked list가 BST로 변환됨
선형 시간이 필요하기 때문에 DLL의 모든 노드가 consant에만 접근할 수 있도록 보증해야 합니다. 가장 좋은 것은 한 번입니다.
모든 노드에 한 번만 접근할 수 있도록 요구하는 이상 뿌리 노드에서 구조하는 것은 틀림없이 안 된다.이런 알고리즘은 BST를 잎 노드부터 구성하게 하고 유연하게 귀속을 운용함으로써 BST를 밑바닥에서 위로 구성하는 과정을 교묘하게 실현했고 BST가 균형적이라는 것을 보장할 수 있다.
#include<iostream>
#include<stack>
using namespace std;
struct BSTNode{
int val;
BSTNode *left;
BSTNode *right;
BSTNode(int v): val(v), left(NULL), right(NULL){}
};
class BSTtoDLL{
public:
BSTNode *func(BSTNode *root){
BSTtoDLLCore(root);
return head;
}
private:
BSTNode* pre = NULL;
BSTNode* head = NULL;
void BSTtoDLLCore(BSTNode *root){
if(!root) return;
BSTtoDLLCore(root -> left);
if(pre){
pre -> right = root;
root -> left = pre;
}else{
head = root;
}
pre = root;
BSTtoDLLCore(root -> right);
}
};
class DLLtoBalancedBST{ public: BSTNode* func(BSTNode* head){ if(!head) return head; int n = 0; for(BSTNode *p = head; p; ++n, p = p -> right); return DLLtoBalancedBSTCore(&head, n); } private: //DLL to BST in place, Time O(N), Space O(LogN) for stack, N is the amount of nodes. //DLL needs to be sorted.
BSTNode* DLLtoBalancedBSTCore(BSTNode** headref, int n){ if(n == 0) return NULL; BSTNode* left = DLLtoBalancedBSTCore(headref, n/2); BSTNode *root = *headref; root -> left = left; *headref = root -> right; root -> right = DLLtoBalancedBSTCore(headref, n-n/2-1); return root; } }; void InorderPrint(BSTNode* root){
if(!root) return;
stack<BSTNode *> st;
while(!st.empty() || root){
if(!root){
root = st.top();
st.pop();
cout << root -> val << ' ';
root = root -> right;
}else{
st.push(root);
root = root -> left;
}
}
cout << endl;
}
int main(){
//Construct oringal BST
BSTNode *root = new BSTNode(5);
BSTNode *left3 = new BSTNode(3);
BSTNode *left1 = new BSTNode(1);
BSTNode *left2 = new BSTNode(2);
BSTNode *right6 = new BSTNode(6);
BSTNode *right7 = new BSTNode(7);
root -> left = left2;
left2 -> left = left1;
left2 -> right = left3;
root -> right = right7;
right7 -> left = right6;
cout << "-------Inorder print BST-------
";
InorderPrint(root);
//Convert BST to DLL
BSTtoDLL bstdll;
BSTNode *head = bstdll.func(root);
BSTNode *p = head;
cout << "-------print converted double linked list----------
";
for(; p->right != NULL; cout << p -> val << ' ', p = p -> right);
cout << endl;
for(; p != NULL; cout << p -> val << ' ', p = p -> left);
cout << endl;
//Convert DLL back to Balenced BST
DLLtoBalancedBST dllbst;
BSTNode *con_root = dllbst.func(head);
cout << "-------Inorder print converted BST-------
";
InorderPrint(con_root);
return 0;
}
하이라이트 부분은 전환 과정이다.
매번 귀속될 때마다headdr라는 노드를 가리키는 바늘이 끝으로 한 번 이동합니다.따라서 모든 노드는 한 번만 방문하고 시간의 복잡도는 선형이다.
우리는 이런 알고리즘이 단방향 체인표에도 적용된다는 것을 발견할 수 있다.물론 단사슬표는 inplace를 보장할 수 없고 반드시 노드를 새로 설명해야 하지만 시간의 복잡도는 여전히 선형이다.
다음은 단방향 체인표의 실현을 제시한다.
정렬된 단방향 Linked list가 BST로 변환됨
#include<iostream>
#include<stack>
using namespace std;
struct ListNode{
int val;
ListNode* next;
ListNode(int v): val(v), next(NULL){}
};
struct BSTnode{
int val;
BSTnode* left;
BSTnode* right;
BSTnode(int v): val(v), left(NULL), right(NULL){}
};
BSTnode *LLtoBSTCore(ListNode **headaddr, int n){ if(n <= 0) return NULL; BSTnode *left = LLtoBSTCore(headaddr, n/2); BSTnode *root = new BSTnode((*headaddr) -> val); root -> left = left; *headaddr = (*headaddr) -> next; root -> right = LLtoBSTCore(headaddr, n-n/2-1); return root; } BSTnode *LLtoBST(ListNode *head){ if(!head) return NULL; int n = 0; ListNode *p = head; for(; p; ++n, p = p -> next); return LLtoBSTCore(&head, n); } int main(){
ListNode *head = new ListNode(1);
ListNode *end = head;
for(int i = 2; i <= 9; end -> next = new ListNode(i++), end = end -> next);
cout << "List:
";
for(ListNode *p = head; p; cout << p -> val << ' ', p = p -> next);
cout << endl;
BSTnode *root = LLtoBST(head);
cout << "BST inorder: " << endl;
stack<BSTnode *> st;
while(!st.empty() || root){
if(!root){
root = st.top();
st.pop();
cout << root -> val << " ";
root = root -> right;
}else{
st.push(root);
root = root -> left;
}
}
cout << endl;
}
하이라이트 부분은 전환 과정이다.
정렬된 시퀀스에 대한 Iterator, 시퀀스를 BST로 변환
다시 미루어 보면 넥스트로만 이동할 수 있는 iterator를 지정하면 이 알고리즘을 통해iterator가 지나간 노드를 BST로 구성할 수 있다.그러나 우리는 사전에 알고 있거나 서열의 길이를 계산해 냈다.
여기서 C#의 구현 코드를 제공합니다.IENumerator는 MoveNext () 를 지원하는 교체기입니다. - 교체기를 뒤로 옮기고, Current 속성 - 교체기가 현재 가리키는 값을 되돌려줍니다.
강조 부분은 IENumrator 기반 구조 프로세스입니다.
인터페이스 IENumerator가 아니기 때문이다.NET CLR의 primitive type(기원 유형)은 IENumerator에 값을 부여하거나 함수 매개 변수로 사용할 때 인용에 따라 전달됩니다. 이것이 바로 우리가 필요로 하는 것입니다.따라서 C#의 구현 코드는 C++에서 두 개의 **를 사용하는 번거로움을 줄였다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
public class BSTNode<T>
{
public T val;
public BSTNode<T> left;
public BSTNode<T> right;
public BSTNode(T v)
{
val = v;
left = null;
right = null;
}
}
/// <summary>
/// Build Binary search tree from given iterator
/// </summary>
public class BuildBST
{
public BSTNode<T> BuildFromIEt<T>(IEnumerator<T> it, int n)
{
if (n == 0) return null; BSTNode<T> left = BuildFromIEt(it, n / 2); it.MoveNext(); BSTNode<T> node = new BSTNode<T>(it.Current); node.left = left; node.right = BuildFromIEt(it, n - n / 2 - 1); return node;
}
}
/// <summary>
/// A class to out put nodes in a tree
/// </summary>
public class TreeTrav
{
public static void Inorde<T>(BSTNode<T> root)
{
if (root == null) return;
Stack<BSTNode<T>> st = new Stack<BSTNode<T>>();
while (root != null || st.Count > 0)
{
if (root == null)
{
root = st.Peek();
st.Pop();
Console.Write(root.val.ToString() + ' ');
root = root.right;
}
else
{
st.Push(root);
root = root.left;
}
}
Console.WriteLine();
}
}
class Program
{
static void Main(string[] args)
{
IEnumerable<int> list = new List<int>() { 1, 2, 3, 6, 7, 9 };
Console.WriteLine("----Original list----");
for (IEnumerator<int> it = list.GetEnumerator(); it.MoveNext(); Console.Write(it.Current.ToString() + ' ')) ;
Console.WriteLine();
BuildBST buildBST = new BuildBST();
BSTNode<int> root = buildBST.BuildFromIEt(list.GetEnumerator(), list.Count());
Console.WriteLine("----Inorder traverse generated BST----");
TreeTrav.Inorde(root);
Console.Read();
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
java 데이터 구조 2차원 트리의 실현 코드일.두 갈래 트리 인터페이스 2 노드 클래스 3. 두 갈래 나무 구현 이 글을 통해 여러분께 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.