`
hellhell
  • 浏览: 24226 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Avl树实现的续

阅读更多
接着看删除部分,删除部分比插入要更难搞一些。对于删除,同样需要分情况讨论。
1.如果是在一个平衡节点下删除,只要把这个节点的高度信息修改就可以了
2.如果是在较长的子树下删除,就把这个节点的高度信息修改成平衡
以上两种情况都不需要进行旋转。
3.如果是在较短的子树下删除,除了更新高度信息外,还需要旋转节点。这时又分3种情况讨论。
3种情况的图如下,直接针对编程就可以了







与插入一样,删除时不必从树根开始更新,记录一个path_top即可。如果某个节点是平衡的,那么删除不会影响到它以上的节点,如果某个节点下的情况和图1相同,那么删除也不会影响到它以上的节点。这时可以把path_top设为该节点。另外,treep是指向删除节点右子树中最小的节点,如果用中序遍历,就是下个节点,将用它的值来代替删除节点。

int avl_delete(node *treep, value_t target)
{
	/* delete the target from the tree, returning 1 on success or 0 if
	 * it wasn't found
	 */
	node tree = *treep, targetn;
	node *path_top = treep;
	node *targetp = NULL;
	direction dir;
	
	while (tree) {
		dir = (target > tree->value);
		if (target == tree->value)
			targetp = treep;
		if (tree->next[dir] == NULL)
			break;
		if (Balanced(tree)
		    || (tree->longer == (1-dir) && Balanced(tree->next[1-dir]))
			) path_top = treep;
		treep = &tree->next[dir];
		tree = *treep;
	}
	if (!targetp)
		return 0;

	/* adjust balance, but don't lose 'targetp' */
	targetp = avl_rebalance_del(path_top, target, targetp);

	/* We have re-balanced everything, it remains only to 
	 * swap the end of the path (*treep == treep) with the deleted item
	 * (*targetp == targetn)
	 */
	avl_swap_del(targetp, treep, dir);

	return 1;
}



这一段代码负责重新平衡树,除了最后一个node更新之外(tree-next[dir] == NULL),其余的都要更新高度信息,如有必要,还有旋转。

node *avl_rebalance_del(node *treep, value_t target, node *targetp)
{
	/* each node from treep down towards target, but
	 * excluding the last, will have a subtree grow
	 * and need rebalancing
	 */
	node targetn = *targetp;

	while (1) {
		node tree = *treep;
		direction dir = (target > tree->value);

		if (tree->next[dir]==NULL)
			break;

		if (Balanced(tree))
			tree->longer = 1-dir;
		else if (tree->longer == dir)
			tree->longer = NEITHER;
		else {
                        // 对比图可以看到,这个是第三幅图的场景
			if (tree->next[1-dir]->longer == dir)
				avl_rotate_3_shrink(treep, dir);
			else // 第一二幅图
				avl_rotate_2_shrink(treep, dir);
                        // 这一句的作用,用targetp本身也在旋转过程中时,需要把它更新,targetp作为旋转的顶,而且三幅图里,都是转到&(*treep)->next[dir]
			if (tree == targetn)
				targetp = &(*treep)->next[dir];
		}
                // 为什么这里是tree而不是treep?
                // 是treep也可以,但是旋转后treep是tree的,这样要多遍历一个节点
		treep = &tree->next[dir];
	}
	return targetp;
}



交换并删除的代码比较简单,如下
void avl_swap_del(node *targetp, node *treep, direction dir)
{
	node targetn = *targetp;
	node tree = *treep;

	*targetp = tree;
	*treep = tree->next[1-dir];
	tree->next[LEFT] = targetn->next[LEFT];
	tree->next[RIGHT]= targetn->next[RIGHT];
	tree->longer = targetn->longer;

	free(targetn);
}


最后是后种旋转的代码实现,都比较直观,如果对着图看。
void avl_rotate_2_shrink(node *path_top, direction dir)
{
	node D, B, C;

	D = *path_top;
	B = D->next[1-dir];
	C = B->next[dir];

	*path_top = B;
	B->next[dir] = D;
	D->next[1-dir] = C;

	if (Balanced(B)) {
		B->longer = dir;
		D->longer = 1-dir;
	} else {
		B->longer = NEITHER;
		D->longer = NEITHER;
	}
}

void avl_rotate_3_shrink(node *path_top, direction dir)
{
	node B, C, D, E, F;
	F = *path_top;
	B = F->next[1-dir];
	D = B->next[dir];
	C = D->next[1-dir];
	E = D->next[dir];

	*path_top = D;
	D->next[1-dir] = B;
	D->next[dir] = F;
	B->next[dir] = C;
	F->next[1-dir] = E;

	B->longer = NEITHER;
	F->longer = NEITHER;
	if (D->longer == dir)
		B->longer = 1-dir;
	if (D->longer == 1-dir)
		F->longer = dir;
	D->longer = NEITHER;
}

  • 大小: 6.5 KB
  • 大小: 6.7 KB
  • 大小: 9.1 KB
分享到:
评论

相关推荐

    avl树实现hash表

    在本项目中,我们将讨论如何结合这两种数据结构,利用avl树实现哈希表,以达到更好的性能效果。 首先,让我们了解一下avl树。avl树是一种自平衡二叉搜索树(BST),它的特点是任何节点的两个子树的高度最大差别不...

    数据结构avl树实现

    AVL树是一种自平衡二叉查找树(Self-Balancing Binary Search Tree),由G. M. Adelson-Velsky和E. M. Landis在1962年提出,因此得名AVL树,它是最早的自平衡二叉查找树之一。在AVL树中,任意节点的两个子树的高度差...

    AVL树的C++实现

    AVL树是一种自平衡的...总结来说,AVL树的C++实现是一个包含节点类、树类和相关操作实现的过程。通过理解和实现这个过程,你可以深入理解自平衡二叉搜索树的工作原理,并能够灵活地在自己的项目中应用这些数据结构。

    红黑树和AVL树的实现

    AVL树的平衡性比红黑树更强,因此在查找效率上通常优于红黑树,但插入和删除操作可能需要更多的旋转,导致更复杂的实现。红黑树的平衡要求相对较宽松,插入和删除操作的代价较低,且在实践中表现良好,是许多语言...

    AVL树的C语言实现

    在C语言中实现AVL树,首先需要定义AVL树的节点结构。每个节点包含三个部分:存储数据的关键字(key)、节点的高度(height)以及指向左子树和右子树的指针。一个简单的节点定义如下: ```c typedef struct AVLNode ...

    AVL树C++实现

    学习AVL树的算法实现,使用c++在vc6.0中进行相应的算法实现,对正在学习算法的孩子有帮助

    数据结构-用户登录实验-二叉查找树AVL树实现

    实验报告可能会详细解释这些操作的步骤,包括如何构建二叉查找树,如何实现AVL树的旋转算法,以及如何在实际应用中使用这些数据结构。此外,报告可能还会包含实验结果的分析,比如不同操作的运行时间比较,以及不...

    AVL树 C++ 实现

    在C++中实现AVL树,我们通常会使用模板类来实现泛型编程,这样可以使得AVL树能够处理不同类型的元素。以下是一个基本的AVL树节点定义: ```cpp template struct AVLNode { T data; int height; AVLNode* left; ...

    AVL树C#实现代码

    7. **调试和测试**:在C#2005中,确保AVL树的实现正确性至关重要,可以通过插入一系列已知的数据,然后进行查找、插入和删除操作,检查结果是否符合预期。同时,调试过程中应关注旋转逻辑,确保每次操作后树依然保持...

    AVL树与红黑树实现(可视化界面)

    `Form1.Designer.cs`、`Form1.resx`和`Form1.cs`可能涉及到用户界面的设计和逻辑,`RBTree.cs`和`AVLTree.cs`分别实现了红黑树和AVL树的类,而`TreeGraphics.cs`可能是用来绘制和展示树的图形部分,`MinAreaDraw.cs`...

    AVL树的实现基于C++语言

    在C++中实现AVL树,我们需要关注以下几个关键点: 1. **节点结构**:AVL树中的每个节点包含一个键值、指向左子树和右子树的指针,以及表示该节点平衡因子的整数值。平衡因子是节点的左子树高度减去右子树高度。典型...

    avl树的实现

    在`avl_tree`这个文件中,很可能包含了AVL树的C++、Java或Python等编程语言的实现,包括节点定义、插入、删除和以括号表示法输出等功能。通过阅读和理解这些代码,你可以深入学习AVL树的工作原理和实际应用。

    一个可以查找中位数的AVL树实现

    综上所述,"一个可以查找中位数的AVL树实现"涉及到的IT知识点包括AVL树的基本概念、平衡因子、旋转操作、节点计数处理、中位数查找算法以及在实际应用中的性能优化。理解并掌握这些知识点,将有助于开发高效的数据...

    AVL树实现的映射

    AVL树是一种自平衡二叉查找树(Binary Search Tree,BST),由Georgy Adelson-Velsky和Emanuel Land...相比于标准库中的红黑树实现,AVL树在保持平衡方面更严格,可能在某些操作上表现得更快,但实现和维护也更为复杂。

    C++ AVL树的实现

    AVL树是一种自平衡二叉查找树(Binary Search Tree,...以上是C++实现AVL树的基础知识点,具体实现过程会涉及更多细节,如旋转的具体代码实现、错误处理等。在实际编码时,还需要注意C++语法和面向对象设计原则的运用。

    AVL树操作图形界面

    6. Java编程:使用Java实现AVL树的优势在于,Java提供了强大的集合框架和图形用户界面库(如Swing或JavaFX),使得开发这样的项目变得相对容易。通过Java代码,我们可以清晰地看到数据结构和算法的实现,同时利用...

    AVL树的细节实现_课程设计文档+代码

    在"AVL树的细节实现_软件设计三班_郭威_1615925218"这个文件中,郭威同学可能详细阐述了AVL树的基本概念,详细描述了插入和删除操作的过程,并给出了相应的C++或Java代码实现。此外,他还可能进行了性能分析和对比...

    C++实现二叉树、搜索二叉树、AVL树

    本话题主要探讨了C++实现的二叉树、二叉搜索树以及AVL树,这些都是高级数据结构,对于优化算法和提高程序效率至关重要。 二叉树是一种特殊的树结构,每个节点最多只有两个子节点,通常分为左子节点和右子节点。在...

    AVL树数据结构平衡二叉查找树

    在计算机科学中,AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。AVL树得名于它的发明者...

Global site tag (gtag.js) - Google Analytics