思路:
尽量保证左子树和右子树含有相同数目的节点。
1.用数组中间元素构造根节点;
2.用中间元素左边的元素构造左子树;
3.用中间元素右边的 元素构造右子树。
代码:
下面的代码给出了两种实现的函数:create_tree1()和create_tree2()。读者可以观察一下二者的区别。
#include<stack>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
class node
{
public:
int key; // value of node
node* lp; // pointer to left child
node* rp; // pointer to right child
node(int k, node*lpp, node* rpp)
{
key = k;
lp = lpp;
rp = rpp;
}
};
void preorder1(node* root)
{ //这个preorder1来自于:http://blog.csdn.net/jiyanfeng1/article/details/8038903
std::stack<node*> st;
if(root!=NULL)
st.push(root);
node* tmp;
while(!st.empty())
{
tmp = st.top();
st.pop();
cout<<tmp->key<<endl;
if(tmp->rp!=NULL)
st.push(tmp->rp);
if(tmp->lp!=NULL)
st.push(tmp->lp);
}
}
node* create_tree1(int* start, int num)//这是个笨的办法
{
if(num<=0)
return NULL;
else if(num==1)
return new node(*start, NULL, NULL);
else
{
node* left_root = NULL;
node* right_root = NULL;
int* mid = start+num/2;
left_root = create_tree1(start, num/2);
if(num>2) //不过要仔细读一下这几句代码
if(num & 1) //弄清一个数列,劈成两半,左半和右半的数量关系
right_root = create_tree1(mid+1, num/2);
else
right_root = create_tree1(mid+1, num/2-1);
return new node(*mid, left_root, right_root);
}
}
node* create_tree2(int* arr, int start, int end)//这个更好
{
if(start>end)
return NULL;
else
{
int mid = (start+end)/2;
node* left = create_tree2(arr, start, mid-1);
node* right = create_tree2(arr, mid+1, end);
return new node(arr[mid], left, right);
}
}
int main()
{
int arr[] = {0,1,2,3,4,5,6,7,8,9,10};
node* root1 = create_tree1(arr, 11);
preorder1(root1);
//检验create_tree2()的作用
node* root2 = create_tree2(arr, 0,10);
preorder1(root2);
int i=0;
scanf("%d",i);
}