java中删除avl树节点方法

    在很多的数据结构书上,关于avl树,都有记录如何进行插入节点以及如何进行树的翻转操作。但对于,如何删除节点,却都是作为练习或者没有提供相应的代码以供参考。笔者,根据插入节点的实现,并部分参考网上其它c++代码,提出一个简单的删除节点的实现,并记录如下。

    删除一个节点的主要步骤如下所示:

  1. 如果是null节点,则直接返回null
  2. 如果删除的值<当前节点,则转入left节点进行递归删除
  3. 如果删除的值>当前节点,则转入right节点进行递归删除
  4. 如果删除的值为当前节点,如果当前节点只有一个子树,则直接返回该子树
  5. 如果删除的值为当前节点,且当前节点有两个子树,则将当前值更改为右子树中最小的节点值,并递归在右子树中删除该节点值
  6. 重新修正该处理节点的height值
  7. 对处理节点进行重新翻转处理,以修正在删除过程中可能出现的树不平衡情况

    经过以上的逻辑,那么实现代码就不那么困难了。简单实现如下所示:

private Node remove(T t, Node node) {
//第1步
		if(node == null)
			return null;
		int cmp = t.compareTo(node.t);
//第2步
		if(cmp < 0) {
			node.left = remove(t, node.left);
//第3步
		} else if(cmp > 0) {
			node.right = remove(t, node.right);
//第5步
		} else if(node.left != null && node.right != null) {
			node.t = findMin(node.right);
			node.right = remove(node.t, node.right);
//第4步
		} else {
			node = node.left == null ? node.right : node.left;
		}
//第6步
		if(node != null)
			node.height = Math.max(height(node.left),height(node.right)) + 1;
//第7步
		node = rotate(node);

		return node;
	}

    对一个节点进行翻转的代码如下所示:

private Node rotate(Node node) {
		if(node == null)
			return null;
		if(height(node.left) - height(node.right) == 2) {
			if(height(node.left.left) >= height(node.left.right))
				return singleLeft(node);
			else
				return doubleLeft(node);
		} else if(height(node.right) - height(node.left) == 2) {
			if(height(node.right.right) >= height(node.right.left))
				return singleRight(node);
			else
				return doubleRight(node);
		}
		return node;
	}

    其余代码就不再列出,如findMin方法,以及左翻转(singleLeft),左双翻转(doubleLeft),这些代码在《数据结构与算法 java》中均有相应实现。

    ps:在前一篇 http://www.iflym.com/index.php/code/201109040001.html 有一个类似的删除c++版,但原实现相比本实现,有点复杂了。经过仔细的分析,本文中的实现,相对简单。但正确性还未验证,如果有不正确的地方,还请来信指出。

转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201109040002.html

相关文章:

作者: flym

I am flym,the master of the site:)

发表评论

邮箱地址不会被公开。 必填项已用*标注