简单结构体二叉树及其应用
结构体二叉树的建立可以使用遍历或者递归,各有其特点,遍历代码复杂但是便于理解与阅读,递归理解更复杂,但是对应代码量要小很多
1.首先时画出我们一会要创建的二叉树。说是树可我更觉得他像一个根型结构。这个二叉树在前序遍历里的结构是:ABD##E##C#FG.去掉空树(#)就是ABDECFG.
首先是创建一个结构体,里面包含左右子节点。以及对应节点的数值。
typedef char Datatype;//这里我暂时用的char型,因为后面导入的是字符
typedef struct TNode{
struct TNode * left;//左子节点
struct TNode * right;//右子节点
Datatype data;//节点数值
}TNode;
接着是对二叉树创建,也是我自己琢磨最久的一个递归,难度在于每次创建二叉树后,需要返回,你已经使用的节点数,因为不是每个二叉树都是满的,存在单子节点。如同创建A的子节点时,我不仅需要得到返回B节点的地址,还需要得到,创建的以B为根时创建下面的树所消耗的数据个数,为此我们这里采用一个结构体作为返回值。就很好的解决了问题。
typedef struct{
TNode * root;//返回创建的节点的地址
int used;//告诉我,创建节点时消耗的数据个数
}Result;
接着我们开始创建这个二叉树。显示节点,然后是递归,我会尽量在代码里把注释写详细,但是还需要重复多看。
Result CreateTree(Datatype preorder[], int size)//创建二叉树,数值采用一个数组里的值
{
if (size == 0)//size值为零,说明这是一个空树。
{
Result result = { NULL, 0 };//空树返回,NULL,使用了0个数据
return result;
}
Datatype rootData = preorder[0];//根节点的赋值,取下数组的第一个值,赋给根。
if (rootData == '#')
{
Result result = { NULL, 1 };//如果遇见#代表遇到了空树,返回NULL,但是用了一个数据’‘#,返回1
return result;
}
TNode * root = CreateNode(rootData);//创建一个节点用root接收
Result leftroot = CreateTree(&preorder[1], size - 1);//对A来说B是左子节点,但是对于D来书,B就是根,我是这么理解的。所以此处传数组第二个数,但是递归回去时,就是新的数组中的第一个数据。
root->left = leftroot.root;//左树创建完毕
Result rightroot = CreateTree(&preorder[1 + leftroot.used], size - 1 - leftroot.used);//同理创建右树,但是这里需要减去我们结构体中返回的使用数据的个数。
root->right = rightroot.root;
Result result = { root, 1 + leftroot.used + rightroot.used };
return result;
}
static TNode * CreateNode(Datatype data)//创建节点
{
TNode *node = (TNode *)malloc(sizeof(TNode));
node->data = dat