二叉树的链表定义:
typedef struct tree
{
int val;
struct tree *lnext;
struct tree *rnext;
}TreeNode;
我们规定二叉树的结构如下:
树的结构:
1 //第一层
1 2 //第二层
1 2 3 4 //第三层
1 2 3 4 5 6 7 8 //第四层
其中的1,2,3,4······代表该层的第几个节点
首先我们创建一个根节点作为树的根:
//创建一个树的根节点
TreeNode* CreateRootTree(void)
{
TreeNode* root = (TreeNode *)malloc(sizeof(TreeNode));
root->rnext = NULL;
root->lnext = NULL;
return root;
}
然后我们再实现添加左孩子和右孩子的函数:
//在树的第layer层的第number个位置添加一个节点作为左孩子,如果双亲不存在就返回错误
void AddLeftNode(TreeNode* p, int layer, int number, int target)
{
TreeNode* Lnode = (TreeNode *)malloc(sizeof(TreeNode)); //先将节点创建好
Lnode->rnext = NULL;
Lnode->lnext = NULL;
Lnode->val = target;
TreeNode* cur = p;
for (int i = 1; i < layer-1; i ++)
{
if (number <= CalAccumulation(2, layer-i)/2) //在当前节点的左子树当中
{
if (cur->lnext == NULL)
{
printf("error\n");
}
else
{
cur = cur->lnext;
}
}
else //在当前节点的右子树中
{
if (cur->rnext == NULL)
{
printf("error\n");
}
else
{
cur = cur->rnext;
number -= CalAccumulation(2, layer-i)/2; //因为来到了右子树,需要重新进行排序
}
}
} //循环结束即找到了需要添加孩子的节点
cur->lnext = Lnode;
}
添加右孩子的函数同理,只需要将最后一句改为
cur->rnext = Lnode;
比如我们需要在第三层的第一个位置添加一个节点作为左孩子(前提是双亲存在):
cur->1 //第一层
1 | 2 //第二层
1 2 | 3 4 //第三层
1 2 3 4 | 5 6 7 8 //第四层
通过number <= CalAccumulation(2, layer-i)/2判断我们需要添加的节点是在左边还是右边
之后我们再递归:
cur->1
1 | 2
1 2|3 4
最后添加左孩子:
cur->lnext = Lnode;
测试:
int main(void)
{
TreeNode* test1 = CreateTestTree();
int count = 0;
int* num = Traversal(test1, &count, 1); //前序遍历
for(int i = 0; i < count; i ++)
{
printf("%d\n", num[i]);
}
return 0;
}
//创建一个作为调试的树
TreeNode* CreateTestTree(void)
{
TreeNode* root = CreateRootTree();
root->val = 1;
AddLeftNode(root, 2, 1, 2);
AddRightNode(root, 2, 2, 3);
AddLeftNode(root, 3, 1, 4);
AddRightNode(root, 3, 2, 5);
return root;
}
结果正确:
全部代码已经上传到GitHub,可自行下载,别忘了点个star:https://github.com/zp-coffee/Algorithms