目录
前提
二叉树的结构
typedef struct BinTreeNode
{
BTElemType data;//BTElemType是二叉树结点数据类型,为了便于代码的修改,可以是int,char......
struct BinTreeNode *leftChild;
struct BinTreeNode *rightChild;
}BinTreeNode;
typedef BinTreeNode *BinTree;
1.有参数的输入型创建
- 按照输入的序列创建二叉树,分别递归的创建左子树和右子树
- 如遇到‘#’代表子树为空
void BinTreeCreate(BinTree *t)
{
assert(t);
BTElemType item;
scanf("%c", &item);
if (item == '#'){//递归结束的条件
*t = NULL;
}
else
{
*t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
assert(*t != NULL);
(*t)->data = item;
BinTreeCreate(&(*t)->leftChild);
BinTreeCreate(&(*t)->rightChild);
}
}
2.无参数的输入型创建
- 有参数的是作为函数参数传进来,无参数是在函数内部创建,然后返回
BinTree BinTreeCreate_1()
{
BTElemType item;
scanf("%c", &item);
if (item == '#'){
return NULL;
}
else
{
BinTreeNode *t = (BinTreeNode *)malloc(sizeof(BinTreeNode));//创建t
assert(t != NULL);
t->data = item;
t->leftChild = BinTreeCreate_1();
t->rightChild = BinTreeCreate_1();
return t;
}
}
3.给定字符串创建二叉树
- 例如ABC##DE##F##G#H##, 字符串遍历到最后遇到‘\0’,或是遇到了'#'就结束递归
- 这里i为什么要传地址,是为了在函数里改变,也会影响主函数
- 注意(*i)++,改变索引的值,才能向后遍历字符串
BinTree BinTreeCreate_2(const char *s, int *i)
{
assert(s);
if (s[(*i)] == '\0' || s[(*i)] == '#'){
return NULL;
}
else{
BinTreeNode *t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
assert(t != NULL);
t->data = s[*i];
(*i)++;
t->leftChild = BinTreeCreate_2(s, i);
(*i)++;
t->rightChild = BinTreeCreate_2(s, i);
return t;
}
}
4.给定先序和中序序列创建二叉树
- 给定先序和中序遍历,可以唯一的确定一个二叉树
- 先序遍历是先根,后左子树,再右子树,那先序序列的第一个元素就是根节点
- 在中序序列中遍历寻找先序序列的第一个元素,以中序序列的这个元素为分界线,左边为树的左子树的结点,右边为右子树的结点
BinTree BinTreeCreate_3(const char *vlr, const char *lvr, int n)
{
if (n == 0){
return NULL;
}
int k = 0;
while (vlr[0] != lvr[k]){//遍历寻找到根结点
k++;
}
BinTreeNode *t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
t->data = lvr[k];
t->leftChild = BinTreeCreate_3(vlr + 1, lvr, k);//参数应该是先序序列的下一个结点,中序序列,中序序列到根节点的长度
t->rightChild = BinTreeCreate_3(vlr + k + 1, lvr + k + 1, n - k - 1);//参数为先序序列的右子树开始位置,中序序列的根节点后面的序列,树的总长度减去左子树长度再减一
return t;
}
5.给定中序和后序序列创建二叉树
- 给定后序和中序遍历,可以唯一的确定一个二叉树
- 后序遍历是先左子树,后右子树,再根节点,那后序序列的最后一个元素就是根节点
- 在中序序列中遍历寻找后序序列的第一个元素,以中序序列的这个元素为分界线,左边为树的左子树的结点,右边为右子树的结点
BinTree BinTreeCreate_4(const char *lrv, const char *lvr, int n)
{
if (n == 0)
return NULL;
int k = 0;
while (lrv[n-1] != lvr[k])
k++;
BinTreeNode *t = (BinTreeNode*)malloc(sizeof(BinTreeNode));
t->data = lvr[k];
t->leftChild = BinTreeCreate_4(lrv,lvr,k);
t->rightChild = BinTreeCreate_4(lrv+k,lvr+1+k,n-k-1);
return t;
}
补充:
只有先序序列和后序序列,不能唯一的确定一个二叉树,例如下面的两个树的先序和后序序列都是ABCD