数据结构(树和二叉树 Part1):https://blog.csdn.net/qq_41605114/article/details/104377414
树的创建(先序)
使用以上的方法,将普通二叉树变成扩展二叉树,即可非常方便的实现树的建立,只需要输入要建立的数的先序遍历结果:
(此处以先序遍历为例子)
//先序遍历创建树
BiNode * CreateTree(char * leaf)
{
if(nullptr == leaf)
return nullptr;
if(position>( (int)strlen(leaf)-1)||strlen(leaf) == 0)
return nullptr;
BiNode * root = new BiNode;
if(leaf[position] == '#')
{
root = nullptr;
position++;
return root;
}
else
{
root->ch = leaf[position];
position++;
root->lchild = CreateTree(leaf);
root->rchild = CreateTree(leaf);
return root;
}
}
程序解释:最开始是保护程序,防止越界操作。
之后:BiNode * root = new BiNode;创建一个新的结点,对于扩展二叉树,先序遍历,先把根节点给root,然后再次分别递归
左右子树即可。完成后最终返回树结点类型的指针。同样,创建的时候使用了new,销毁的时候就要delete。
下面以最简单的树举例说明:先序,从根结点触发,输入字符串为“DH##I##”
很显然叶子结点的后面是两个##,进入程序先为结点分配空间,可以非常确定的是,最先进入程序的一定是根结点,D
然后判断,是不是#,如果是,直接返回nillptr,如果不是,则给根基结点赋值,A
之后字符串的下标增加,先进行左子树的创建,左子树到底是多少个结点的根,迭代即可,完成左子树后即可机械右子树的赋值操作。
递归程序书写思路:
所有的二叉树都是由以上这种最基本的二叉树组成的,在最基本的二叉树上能够实现的方法,放诸四海皆如此。
字符串的输入是扩展二叉树先序遍历的结果, D(根)H(左叶子结点)##(扩展虚节点)I(右叶子结点)##(扩展虚节点)
程序也是跟着输入写的,首先进入的是根结点,那么直接给根结点赋值:root->ch = leaf[position];
之后输入是左叶子结点,那么左叶子结点和两个虚结点又组成了一颗新树,而且左叶子结点是新的根,
还是一样的操作,给根赋值root->ch = leaf[position];,有公共的操作,此时就可以选择进行递归了,
左叶子结点完成后,是左虚结点,左虚结点本身就是假设的,直接赋值为空即可,然后直接返回,因为虚结点不可能是根
如此便在根赋值前面加上一段if(leaf[position] == '#')
整个程序递归思路如上。
所有递归程序的思路:
以最小单位进行执行,找共性操作,书写程序基本框架,以最复杂情况进行考虑,完成程序剩余部分 ,避免遗漏特殊情况。
就像上面创建树一样,D是根,H也是新的根,D可能也是某棵树的结点,从最简单的树入手,分析基本操作,但是也不要忽略树的复杂性。
在后续(Part3)中,线索二叉树的遍历也是如此。
销毁程序如下:
//树的释放
void FreeTree(TreadedBiNode * root)
{
if(nullptr == root)
return;
FreeTree(root->lchild);
FreeTree(root->rchild);
delete root;
}
具体创建过程如下:
准备工作和具体操作:
//前期准备
int position = 0;//全局变量
//定义一个全局变量或者静态局部变量,为了控制字符串的输入
//具体执行
char * InPut = "AB#D##C##";//先序遍历创建树
BiNode * MyRoot = CreateTree(InPut);
qDebug()<<position;
recursion(MyRoot);
FreeTree(MyRoot);
//稍微对recursion进行了改进
//先序遍历
void recursion(BiNode * root)
{
if(nullptr == root)
{
qDebug()<<"序号:"<<'#';
return;
}
qDebug()<<"序号:"<<root->ch;
//递归遍历左子树
recursion(root->lchild);
//递归遍历右子树
recursion(root->rchild);
}
输出:
我们再看一个例子,以下面这个树为例子
使用这个树,和常规的先序遍历,再次进行测试,输入:AB#CD##E##F#GH###
char * InPut = "AB#CD##E##F#GH###";//先序遍历创建树
BiNode * MyRoot = CreateTree(InPut);
qDebug()<<position;
recursion(MyRoot);
FreeTree(MyRoot);
创建树并且遍历
(图源:大话数据结构)