根据给定不同的数据结构,构建二叉树的方法也有好几种。
我这里先说一种相对简单点的,给定的数据结构是一个数组,数组存放的是一个完全二叉树,没有的节点用‘@’符号表示。
如下图的树
真正的树:
转化为数组表示的树:
数组表示为:
index | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
data | 1 | 2 | 3 | 4 | 5 | @ | 6 | @ | 7 | @ | 8 | @ | @ | 9 | A |
在数组中取两个索引,一个是当前创建节点所在的位置(pcurrc),一个是父节点所在的位置(pfatherc)。
用一个队列保存 已创建的节点,但还没有赋予左右孩子的节点(que);
对于pfatherc每前进一步,pcurrc都要前进两步。
构建二叉树算法:
取出队列中的头结点作为pfatherc。
如果pfatherc是‘@’,则说明它的左右孩子都为‘@’(即无左右孩子),pcurrc前进两步
否则,说明他可能有左右孩子;判断pcurrc是否为‘@’,
若是,则此节点不是孩子节点,pcurrc前进一步。
若否,则此节点是孩子节点,创建此节点,并加入队列。
源代码
树节点结构体声明:
struct TreeNode
{
char data;
TreeNode *plc;
TreeNode *prc;
};
建树代码:
TreeNode* BulidTree(char* pdata,int len)
{
TreeNode* proot;
char* pfatherc = pdata;
char* pdataend = pdata + len;
char* pcurrc = pdata;
TreeNode* pfathert = NULL;
TreeNode* pcurrt = NULL;
queue<TreeNode*> que;
pcurrt = new TreeNode; //push the first node;
pcurrt->plc = NULL;
pcurrt->prc = NULL;
pcurrt->data = *pcurrc++;
proot = pcurrt;
que.push(pcurrt);
while ( !que.empty() && pcurrc < pdataend)
{
if (*pfatherc == '@')
{
pcurrc += 2;
++pfatherc;
}
else
{
pfathert = que.front();
que.pop();
//left child
if (*pcurrc == '@')
{
++pcurrc;
}
else
{
pcurrt = new TreeNode;
pcurrt->plc = NULL;
pcurrt->prc = NULL;
pcurrt->data = *pcurrc++;
que.push(pcurrt);
pfathert->plc = pcurrt;
}
//right child
if (*pcurrc == '@')
{
++pcurrc;
}
else
{
pcurrt = new TreeNode;
pcurrt->plc = NULL;
pcurrt->prc = NULL;
pcurrt->data = *pcurrc++;
que.push(pcurrt);
pfathert->prc = pcurrt;
}
++pfatherc;
}
}
return proot;
}