北邮数据结构平衡二叉树报告概论
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构
实
验
报
告
实验名称:平衡二叉树
1.实验目的和内容
根据平衡二叉树的抽象数据类型的定义,使用二叉链表实现一个平衡二叉树。
二叉树的基本功能:
1、平衡二叉树的建立
2、平衡二叉树的查找
3、平衡二叉树的插入
4、平衡二叉树的删除
5、平衡二叉树的销毁
6、其他:自定义操作
编写测试main()函数测试平衡二叉树的正确性。
2. 程序分析
2.1 存储结构
struct node
{
int key; //值
int height; //这个结点的父节点在这枝最长路径上的结点个数
node *left; //左孩子指针
node *right; //右孩子指针
node(int k){ key = k; left = right = 0; height = 1; } //构造函数};
2.2 程序流程
2.3 关键算法分析(由于函数过多,在此只挑选部分重要函数)
算法1:void AVL_Tree::left_rotate(node *&x)
[1] 算法功能:对 R-R型进行调整
[2] 算法基本思想:将结点右孩子进行逆时针旋转
[3] 算法空间、时间复杂度分析:都为0(1)
[4] 代码逻辑
node *y = x->right; y为x的右孩子
x->right = y->left; 将y的左孩子赋给x的右孩子 y->left = x; x变为y的左孩子
fixheight(x); 修正x,y的height值
fixheight(y);
x = y; 使x的父节点指向y 算法2:void A VL_Tree::right_rotate(node *&x)
[1] 算法功能:对L-L型进行调整
[2] 算法基本思想:将左孩子进行顺时针旋转
[3] 算法空间、时间复杂度分析:都为0(1)
[4] 代码逻辑
node *y = x->left; //y为x的左孩子 x->left = y->right; y的右孩子赋给x的左孩子
y->right = x; x变为y的右孩子
fixheight(x); 修正x和y的height值
fixheight(y);
x = y; 使x的父节点指向y
算法3:node*& A VL_Tree::balance(node *&p)
[1] 算法功能:对给定结点进行平衡操作
[2] 算法基本思想:通过平衡因子判断属于哪种情况,再依照情况进行平衡
[3] 算法空间、时间复杂度分析:没有递归和循环,都为O(1)
[4] 代码逻辑
fixheight(p); //修正P的height值
if (bfactor(p) == 2) 平衡因子为2,为L-?型
if (bfactor(p->left) < 0) P的左孩子平衡因子<0时,为L-R型,执行left_rotate(p->left); 相关平衡操作,若>0,为L-L型。
right_rotate(p);
}
else if (bfactor(p) == -2) 平衡因子为2 ,为R-?型
{
if (bfactor(p->right)>0) P的右孩子平衡因子>0,为R-L型
right_rotate(p->right); 小于0时,为R-R型
left_rotate(p);
}
fixheight(p); 修正平衡后的P的height值
return p;
算法4:node* A VL_Tree::remove(node *&p, int k)
[1] 算法功能:删除给定key值的结点
[2] 算法基本思想:首先通过递归找到待删除结点,如果其没有右孩子,直接将其
删除,将其左孩子链上去。若有右孩子,找到右枝中的最小结点代替待删除结
点,对改变后的结点进行平衡。注意右孩子要删除其中的最小结点
[3] 算法空间、时间复杂度分析:有递归,递归次数最多为深度,时间复杂度0
(nlogn),空间复杂度0(logn)
[4] 代码逻辑
if (k < p->key) K小于根节点,在左枝中寻找p->left=remove(p->left, k); 递归
else if (k>p->key) K大于根节点,在右枝中寻找p->right=remove(p->right, k); 递归
else 找到待删除结点
{
node *q = p->left; q为删除结点的左孩子
node *r = p->right; p为删除结点右孩子
delete p;
if (!r) //没有右子树
return q; 直接将左孩子返回,相当于直接删除p node* min = findmin(r); //有右子树时,找到右枝中的最小值
min->right=removein(r); 使删除最小值后的右枝变为min的右枝
min->left = q; p的左孩子变为min的左孩子,相当于删除了p,
balance(min); 对min进行balance操作
return min;
}
balance(p); 每次递归完都对p进行平衡操作
return p;
算法5:void A VL_Tree::insert(node *&p, int k)
[1] 算法功能:一边插入结点一边进行平衡
[2] 算法基本思想:按照构建排序二叉树的方法插入结点,每插入一次后判断是否
需要平衡
[3] 算法空间、时间复杂度分析:插入节点寻找位置需要递归,时间复杂度O(logn)
空间复杂度O(logn)
[4] 代码逻辑