关于数据结构Mooc后的每一道答案
基本我都已经给出了详解
希望能对大家有所帮助
收藏一下也是方便大家查找吧
希望大家一起进步!
(c语言)浙大数据结构Mooc作者答案集
下面是关于这道题的谷歌翻译
我估摸着可能有hxd题目没看懂就先过来看题意的(就是我) 所以总起先来分析一下题意:
这个题目的意思就是给定一串数列 然后把数列填充到完全平衡二叉树
AVL又称平衡二叉树 :任何结点的左子数和右子树高度差不超过2
完全二叉树:排布是从左到右依次排布结点 且不会跳重开来
满二叉树: 完全二叉树是由满二叉树引出 除了最后一排的节点都是叶外 其余的儿子树全满hhh (我是这样理解的)
关于这道题的思路
真让我自己做还真没做出来 还是一样借鉴了他人的思路还有陈越姥姥的思路 然后看完自己下手一步步慢慢推出来的
我刚开始想着 因为
首先利用之前做那道平衡二叉树的插入的经验 就是如何调整每次的输入后保证是完全二叉树 之后试想了很久尝试了很久但是也失败了 也根本没想过是通过输入结点个数 从而确定现有结构 再向里面填充 并且利用数组来进行层序输出即可
我们实现层序排列是通过数组排列 且通过有序数组来进行输出的
我们的解题思路就是 先对输入的数列从小到大排序 并且排序后
因为是完全平衡二叉树 我们不难知道当前的根节点在数组中的位置就是
左节点数+1 左节点数可以通过我们自己设计一个函数而计算得到
而把根节点放入存储输出数组的第一个位置 而后面放入根节点的在数组的相对位置都可以通过计算左节点数 +1 从而得到
存储输出数组的位置规律
通过上面图不难发现 左节点在存储数组位置就是上面结点当前位置*2 +1
而右节点在存储数组位置就是左节点+1
如果还不理解思路的话 可以结合下面的代码实现加以理解
下面给出代码实现
#include <stdio.h>
#include <math.h>
#define MAX 1000
//将需要的都用全局变量方便后面函数使用
//Tree就是我们最后层序遍历用的数组
int Tree[MAX];
int totalnumbers;
int Data[MAX];
//求左节点个数的算法
int GetLeftNodes(int totalnumbers)
{
int h,leftmumbers;
//这里是用了换底公式
//h = log2(totalnumber+1) 这里的h是不包含最后一层的高度的
h = log(totalnumbers+1)/log(2);
//上面h层总结点数
int hnumbers= pow(2,h) - 1;
//最后一层的左节点最多个数
int halfrootnumbers = pow(2,h-1);
leftmumbers = (hnumbers -1)/2 + ((totalnumbers - hnumbers) < halfrootnumbers ? (totalnumbers - hnumbers) : halfrootnumbers);
return leftmumbers;
}
//存放入最后需要的层序遍历Tree的函数
void FindAnswer(int left,int right,int root)
{
//刚开始借鉴别人的代码看到这里是一脸懵逼的 在这里我解释一下
//当递归到最后的时候只有一个结点了 没有左右儿子的时候
//我们下面l是等于0的 但下面函数也会继续
//FindAnswer(left,left+l-1, leftroot);
//FindAnswer(left+l+1,right,rightroot);
//结合下面的FindAnswer函数 最后的输入的时候要不right比left少1
//要不left比right多1 此时n=0时就说明结束了
int n = right - left + 1;
if(!n)
return;
int l = GetLeftNodes(n);
//这里自己推一下
Tree[root] = Data[left+l];
int leftroot = 2 * root +1;
int rightroot = leftroot + 1;
//利用递归 left+l在数组中是当前的根节点位置
FindAnswer(left,left+l-1, leftroot);
FindAnswer(left+l+1,right,rightroot);
}
void Sort(int Data[])
{
//由于C语言没有排序函数 所以只能自己用一个冒泡排序
int i,j,temp;
for(i=0;i<totalnumbers-1;i++)
{
for(j=i+1;j<totalnumbers;j++)
{
if(Data[i]>Data[j])
{
temp = Data[i];
Data[i] = Data[j];
Data[j] = temp;
}
}
}
}
void Print(int Tree[])
{
//输出
int i=0;
while(i<totalnumbers-1)
printf("%d ",Tree[i++]);
printf("%d",Tree[i]);
}
int main()
{
int i;
scanf("%d",&totalnumbers);
for(i=0;i<totalnumbers;i++)
scanf("%d",&Data[i]);
Sort(Data);
FindAnswer(0,totalnumbers-1,0);
Print(Tree);
return 0;
}
思路就是如上
与大家一起进步