平衡二叉树(AVL)实现(1)
2010-10-08 17:06 Clingingboy 阅读(1144) 评论(0) 编辑 收藏 举报http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html
修改自陈广老师
1.Node
public class Node { public int Data { get; set; } //记录平衡因子 public int BF { get; set; } public Node Left { get; set; } public Node Right { get; set; } public Node(int val) { Data=val; } }
2.操作,对外开放的只有添加和删除操作,并记录了一个头节点
public interface IBinaryTree { Node Head { get; } bool Add(int value); bool Remove(int value); }
3.BinarySearchTree
public class BinarySearchTree:IBinaryTree { private Node[] path = new Node[32]; private int currentIndex; private Node _head; public Node Head { get { return _head; } } public bool IsEmpty { get { return _head == null; } } public bool Add(int value) { return true; } public bool Remove(int value) { return false; } }
添加节点
新增的节点默认平衡因子为0,但会影响上层节点
1.当节点为空时,添加节点
public bool Add(int value) { if (IsEmpty) { _head = new Node(value); _head.BF = 0; return true; } }
2.寻找插入点,并插入节点
如果要插入6
1.首先6跟根节点20比较,选左节点
2.然后6跟15比较,再选15的左节点
3. 由于12没有子节点,所以就找到了插入点(现在还不能插入).并记录该节点
4.6肯定是12的子节点;6跟12比较,6比12小,所以为12的左节点
代码实现1-3
下面代码用prev变量 记录插入点即12
currentIndex = 0; Node prev = null, current = _head; while (current != null) { prev = current; current = (value < prev.Data) ? prev.Left : prev.Right; }代码实现4
下面代码先声明一个节点,然后加入到父节点中
current = new Node(value);
current.BF = 0;
if(value < prev.Data)
{ prev.Left = current; }
else
{ prev.Right = current; }
改变父节点路径平衡因子
以上的操作属于二叉搜索树的操作,接下来的才是关键.
在添加完节点后,我们还要同时变更父节点的平衡因子
1.由于平衡因子等于节点的左节点高度-节点的右节点高度
所以当添加的节点为左节点时,父节点平衡因子+1,反之则-1
2.改变所有经过节点的平衡因子,所以要把这些节点记录下来,必经是一层层自下而上的父节点
3.平衡因子是叠加的,而不是赋值的
int bf = 0; while (currentIndex > 0) {
//确定节点添加的方向是左还是又
bf = (value < path[currentIndex - 1].Data) ? 1 : -1; path[--currentIndex].BF += bf; //叠加
bf = path[currentIndex].BF; //取当前节点平衡因子
}
如果平衡因子的绝对值等于2则开始旋转
上面变更平衡因子后,接下来还要判断bf的值得,如果绝对值等于2就需要开始旋转操作.
if (bf == 0) { return true; } else if (bf == 2 || bf == -2) { RotateSubTree(bf); return true; }
至此添加的操作全部完毕
下面将是旋转部分,分开写...