Introduction
This article comes from a topic from Google:
How to merge the binary search tree into balanced binary search tree. How to merge the binary search tree into balanced binary search tree. Let there is m elements in first tree and n elements in the other tree. Your merge function should take O (M+n) time and does it in place.
http://www.careercup.com/question?id=5261732222074880
To complete in linear time, and to require in place, it is not difficult to think of converting BST to a double linked list.
Then merge the two DLLs. However, is there a linear time complexity algorithm to convert the DLL into BST?
Here is the content to be described in this article, the algorithm reference from
http://www.geeksforgeeks.org/in-place-conversion-of-sorted-dll-to-balanced-bst/
Sorted Double linked list converted to BST
Because linear time is required, it is important to ensure that each node on the DLL is accessed only consant times, preferably once.
Since it is required that each node be accessed only once, it is certainly not possible to construct from the root node. This algorithm allows BST to be constructed from the leaf nodes, and by using recursion flexibly, the process of constructing BST from bottom up is cleverly realized, and the BST is guaranteed to be balanced.
#include <iostream>#include<stack>using namespacestd;structbstnode{intVal; Bstnode*Left ; Bstnode*Right ; Bstnode (intv): Val (v), left (null), right (null) {}};classbsttodll{ Public: Bstnode*func (Bstnode *root) {Bsttodllcore (root); returnHead; } Private: Bstnode* Pre =NULL; Bstnode* head =NULL; voidBsttodllcore (Bstnode *root) { if(!root)return; Bsttodllcore (Root-Left ); if(PRE) {preright =Root; Root-left =Pre; }Else{Head=Root; } Pre=Root; Bsttodllcore (Root-Right ); }};classdlltobalancedbst{ Public: Bstnode* Func (bstnode*head) { if(!head)returnHead; intn =0; for(Bstnode *p = head; p; ++n, p = PRight ); returnDlltobalancedbstcore (&head, N); } Private: //DLL to BST A, Time O (n), Space O (logn) for stack, N is the amount of nodes. //DLL needs to be sorted.bstnode* Dlltobalancedbstcore (bstnode** headref,intN) { if(n = =0)returnNULL; Bstnode* left = Dlltobalancedbstcore (Headref, n/2); Bstnode*root = *Headref; Root-left =Left ; *headref = rootRight ; Root-right = Dlltobalancedbstcore (Headref, n-n/2-1); returnRoot; }};voidInorderprint (bstnode*root) { if(!root)return; Stack<bstnode *>St; while(!st.empty () | |root) { if(!root) {Root=St.top (); St.pop (); cout<< Root, Val <<' '; Root= rootRight ; }Else{St.push (root); Root= rootLeft ; }} cout<<Endl;}intMain () {//Construct Oringal BSTBstnode *root =NewBstnode (5); Bstnode*left3 =NewBstnode (3); Bstnode*LEFT1 =NewBstnode (1); Bstnode*LEFT2 =NewBstnode (2); Bstnode*RIGHT6 =NewBstnode (6); Bstnode*RIGHT7 =NewBstnode (7); Root-left =left2; LEFT2-left =left1; LEFT2right =left3; Rootright =right7; RIGHT7-left =Right6; cout<<"-------inorder print BST-------\ n"; Inorderprint (root); //Convert BST to DLLBsttodll Bstdll; Bstnode*head =Bstdll.func (root); Bstnode*p =Head; cout<<"-------Print converted double linked list----------\ n"; for(; P->right! = NULL; cout << P-Val <<' ', p = PRight ); cout<<Endl; for(; p! = NULL; cout << P-Val <<' ', p = PLeft ); cout<<Endl; //Convert DLL back to balenced BSTDlltobalancedbst Dllbst; Bstnode*con_root =Dllbst.func (head); cout<<"-------inorder Print converted BST-------\ n"; Inorderprint (Con_root); return 0;}
Highlight part of the conversion process.
Each time recursion is headaddr, the pointer to the node moves to the end. So each node is accessed only once, and the time complexity is linear.
We can see that this algorithm is also applicable to the one-way linked list. Of course the single-link list does not guarantee in-place, it must be a new declaration node, but the time complexity is still linear.
Further more, for a given iterator that can only move to next, the algorithm can be constructed to construct the iterator passing node as BST. However, we need to save the starting position of the iterator because the algorithm needs to traverse one side to note the number of nodes.
The implementation on the one-way list is given below.
Sequenced one-way linked list converted to BST
#include <iostream>#include<stack>using namespacestd;structlistnode{intVal; ListNode*Next; ListNode (intv): Val (v), next (NULL) {}};structbstnode{intVal; Bstnode*Left ; Bstnode*Right ; Bstnode (intv): Val (v), left (null), right (null) {}}; Bstnode *lltobstcore (ListNode **headaddr,intN) { if(N <=0)returnNULL; Bstnode*left = Lltobstcore (headaddr, n/2); Bstnode*root =NewBstnode ((*HEADADDR)val); Root-left =Left ; *headaddr = (*HEADADDR)Next; Root-right = Lltobstcore (headaddr, n-n/2-1); returnRoot;} Bstnode*lltobst (ListNode *head) { if(!head)returnNULL; intn =0; ListNode *p =Head; for(; p; ++n, p = Pnext); returnLltobstcore (&head, n);}intMain () {ListNode*head =NewListNode (1); ListNode*end =Head; for(inti =2; I <=9; End-Next =NewListNode (i++), end = Endnext); cout<<"List: \ n"; for(ListNode *p = head; p; cout << P-Val <<' ', p = Pnext); 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= rootRight ; }Else{St.push (root); Root= rootLeft ; }} cout<<Endl; }
Highlight part of the conversion process.
Binary Tree Series-Two forks search tree-Convert ordered list to BST in linear time