In this problem, it is like the classical recursion example: draw the ruler as the sign of algorithms 4th textbook.
In order to draw a balanced tree from an array, we need to keep left subtree.height similar or equal to right subtree.height.
First need to find the root--->we can choose the middle number of the array. then recursively go to left construction and right construction.
Here is the main algorithm:
note: the first parameter seems no use of the head, but it is a good one. By using call-by-reference of the head pointer, we don't need to declare head as a global variable, and it can be explicitly shown in the recursion part to tell the order of recursion: left tree first and then right one.
void min_BST(BinNode* &head, BinNode *parent, int a[], int start, int end){
if(start<=end){
int mid=(start+end)>>1;
node[cnt].data = a[mid];
node[cnt].parent = parent;
head = &node[cnt++];
min_BST(head->lChild, head, a, start, mid-1);
min_BST(head->rChild, head, a, mid+1, end);
}
}
Here is the whole code.
// Ch4-3: create a balanced minimal BST from an ordered array
#include
#include
using namespace std;
const int maxn=100;
int jerry = 0;
struct BinNode{
int data;
BinNode *parent, *lChild, *rChild;
};
BinNode node[maxn];
int cnt;
//BinNode *head = NULL; if use ver2, need to declare head as global var
void init(){
memset(node, '\0', sizeof(node));
cnt=0;
}
void min_BST(BinNode* &head, BinNode *parent, int a[], int start, int end){
if(start<=end){
int mid=(start+end)>>1;
node[cnt].data = a[mid];
node[cnt].parent = parent;
head = &node[cnt++];
min_BST(head->lChild, head, a, start, mid-1);
min_BST(head->rChild, head, a, mid+1, end);
}
}
// if "BinNode* &head" is not inside of method, then it must be a global variable
// so as to be changed every time, also, it will be less clear in recursion:
// which is first? lChild or rChild. So I prefer to have "BinNode* &head" inside
// of the method, need to make a call by reference that we can modify the value
/*
void min_BST_ver2(BinNode *parent, int a[], int start, int end){
if(start <= end){
int mid = (start + end)>>1;
node[cnt].data = a[mid];
node[cnt].parent = parent;
head = &node[cnt++];
min_BST_ver2(head, a, start, mid-1);
min_BST_ver2(head, a, mid+1, end);
}
}
*/
int height(BinNode* head){
if(head==NULL)
return 0;
else{
return max(height(head->lChild), height(head->rChild))+1;
}
}
int main(){
init();
int a[] = {
0,1,2,3
};
BinNode *head = NULL; //if use ver2, need to declare head as global var
min_BST(head, NULL, a, 0, 3);
cout<<"\nheight: "<
<
data<
lChild)<<" " <
lChild << "dizhi\n"; cout<
lChild->data<
rChild->data<
<<"\n"; cout<
rChild->rChild->data<
<<"\n"; cout<
<
And output:
1
0
2
3
In order to practice class and template, here is a formal version:
// Ch4.3: Given a binary search tree, design an algorithm which creates a linked list of all the nodes at each depth (i.e., if you have a tree with depth D, you’ll have D linked lists).
// based on Hawstein's solution
// and modified into class version according to zyli github
#include
#include
#include
using namespace std;
template
class BinNode{
public:
T key;
BinNode
*parent, *lChild, *rChild; BinNode(){} BinNode(T t): key(t), parent(NULL), lChild(NULL), rChild(NULL){} }; template
class BTree{ private: BinNode
*m_root; public: BTree(): m_root(NULL){} BTree(BinNode
*t): m_root(t){} BinNode
* getRoot() const{return m_root;} // node the 1st parameter cannot be "BinNode* &pnode" BinNode
* balanceTree(BinNode
* pnode, BinNode
*parent, T *arr, int low, int high){ if(low>high || arr == NULL) return NULL; int mid = (low+high)>>1; pnode = new BinNode
(arr[mid]); pnode->parent = parent; pnode->lChild = balanceTree(pnode->lChild, pnode, arr, low, mid-1); pnode->rChild = balanceTree(pnode->rChild, pnode, arr, mid+1, high); return pnode; } void PrintPre(BinNode
*pnode) { if(pnode == NULL) return; cout << pnode->key << " "; PrintPre(pnode->lChild); PrintPre(pnode->rChild); } }; int main(){ cout << "hello"<
*bt = new BTree
(); BinNode
*proot = bt->balanceTree(bt->getRoot(), NULL, arr, low, high); bt = new BTree
(proot); bt->PrintPre(bt->getRoot()); }