数据结构与算法----二叉树的储存和生成

1,207 阅读1分钟

介绍二叉树的储存之前,先介绍一下二叉树的父节点与子节点之间的线性关系

就以下面的满二叉树为例,通过索引值会发现,每一层的参数会与层数有明显的线性关系,即2倍关系,毕竟二叉树每多一层节点数则会变为原来的两倍,设n(0 <= n <= ∞)为当前节点索引,则左节点索引为2n + 1, 右节点索引为2n + 2

如果将索引号从1开始,相信会感觉更明确,如下图所示,明显最左侧节点为上层节点的2倍关系,即左节点为2n,右节点为2n+1

下面就根据上面第一个图总结的规律来实现二叉树的储存和生成

二叉树的储存

二叉树的储存就是把一个二叉树结构,这里保存到一个线性数组中方便储存,利用上面总结出来的特性,以根节点索引为0,递归地按照对应索引找到其两个子节点,存放到数组中对应位置。如果为空的子树,由于那部分数据不会往数组存放,所以数据则为0(或者为空)

//更新result数组,例如二叉树的性质,节点和子节点之间的关系,第n个节点索引为 2n + 1,右节点为2n + 2
void updateResult(LSTree *node, int *result, int n) {
    if (!node) return;
    result[n] = node->data;
    updateResult(node->lChild, result, 2*n + 1);
    updateResult(node->rChild, result, 2*n + 2);
}

//保存一个二叉树到数组里
void saveTree() {
    int result[20] = {0};
    LSTree *root = NULL; //假设有值
    updateResult(root, result, 0);
    //这里result即存放好了
}

二叉树的生成

二叉树的生成同储存相似,通过上面的规律,反向递推生成二叉树。

从数组索引第0个开始,那么其左子树的索引为2n + 1, 右子树为 2n + 2,如果发现数组越界,则不生成即可,以此递归则可以生成二叉树

//利用二叉树的父子节点关系解决
LSTree * updateTree(int *result, int n, int maxLength) {
    if (n <= maxLength) return NULL; //越界不处理
    
    LSTree *node = (LSTree *)malloc(sizeof(LSTree));
    node->data = result[n];
    node->lChild = updateTree(result, 2*n + 1, maxLength);
    node->rChild = updateTree(result, 2*n + 2, maxLength);
    return node;
}

//二叉树的生成,通过数组生成二叉树
void generateTree(int *result, int maxLength) {
    if (maxLength < 1) return;
    
    LSTree *root = updateTree(result, 0, maxLength);
    //这里生成的root就是result数组生成的二叉树了
}