AVL(二叉平衡树) 的实现

一颗AVL树是其每个节点的左子树与右子树的高度最多差1的二叉查找树。

在插入过程中,利用旋转的办法保持这个性质。

共分四种情形:

1、  树T的左孩子的左子树上新插入节点导致破坏平衡性:

如下图左边所示,因为在子树X中新加入一个节点,导致k2处的平衡性被破坏

通过如右边所示的旋转,可以使得整棵树重新变得平衡。

AVL(二叉平衡树) 的实现

2、 树T的右孩子的右子树上新插入节点导致破坏平衡性

这种情形跟上面那种情形是对称的。

AVL(二叉平衡树) 的实现

3、树T的左孩子的右子树上新插入节点导致破坏平衡性

此时照搬情形1的旋转方法已经不能奏效了。

AVL(二叉平衡树) 的实现

考虑将Y这部分散开来看:

AVL(二叉平衡树) 的实现

可经由两次旋转解决问题:

AVL(二叉平衡树) 的实现

可以发现,经过第一次旋转之后,问题已经变成了情形1,可再进行一次单旋转解决:

AVL(二叉平衡树) 的实现

4、树T的右孩子的左子树上新插入结点,这时与情形3完全对称,可类似解决。

以下是实现部分。

仅实现插入操作,删除一般是惰性的。还有一点假设相同元素不出现在树结构中。

avl.h

#pragma once

using Elemtype = int;

struct AvlNode;

typedef struct AvlNode *Position;

typedef struct AvlNode *AvlTree;



//AvlTree MakeEmpty(AvlTree T);

//Position Find(Elemtype X, AvlTree T);

//Position FindMin(AvlTree T);

//Position FindMax(AvlTree T);



AvlTree Insert(Elemtype X, AvlTree T);

//AvlTree Delete(Elemtype X, AvlTree T);



//Elemtype Retrieve(Position P);

 avl.cpp

#include "avl.h"

#include<cstdio>

#include<cstdlib>

#include<cassert>

#include<algorithm>

struct AvlNode{

	Elemtype Element;

	AvlTree Left;

	AvlTree Right;

	int Height;

};



static int Height(Position p){

	if (p == nullptr)

		return -1;

	else

		return p->Height;

}

static Position SingleRotateWithLeft(Position K2){

	Position K1;

	K1 = K2->Left;

	K2->Left = K1->Right;

	K1->Right = K2;



	K2->Height = std::max(Height(K2->Left), Height(K2->Right)) + 1;

	K1->Height = std::max(Height(K1->Left), Height(K1->Right)) + 1;



	return K1; /*New root*/

}

static Position SingleRotateWithRight(Position K2){

	Position K1;

	K1 = K2->Right;

	K2->Right = K1->Left;

	K1->Left = K2;



	K2->Height = std::max(Height(K2->Left), Height(K2->Right)) + 1;

	K1->Height = std::max(Height(K1->Left), Height(K1->Right)) + 1;



	return K1; /*New root*/

}

static Position DoubleRotateWithLeft(Position K3){

	K3->Left = SingleRotateWithRight(K3->Left);

	return SingleRotateWithLeft(K3);

}

static Position DoubleRotateWithRight(Position K3){

	K3->Right = SingleRotateWithLeft(K3->Right);

	return SingleRotateWithRight(K3);

}

AvlTree Insert(Elemtype X, AvlTree T){

	if (T == nullptr){

		/*Create and return a one-node tree*/

		T = (AvlTree)malloc(sizeof(struct AvlNode));

		assert(T != nullptr, "Out of Space");

		T->Element = X; T->Height = 0;

		T->Left = T->Right = nullptr;

	}

	else if (X < T->Element){

		T->Left = Insert(X, T->Left);

		if (Height(T->Left) - Height(T->Right) == 2){

			if (X < T->Left->Element){

				T = SingleRotateWithLeft(T);

			}

			else{

				T = DoubleRotateWithLeft(T);

			}

		}

	}

	else if (X > T->Element){

		T->Right = Insert(X, T->Right);

		if (Height(T->Right) - Height(T->Left) == 2){

			if (X > T->Right->Element){

				T = SingleRotateWithRight(T);

			}

			else{

				T = DoubleRotateWithRight(T);

			}

		}

	}

	/*Else X is in the tree already; we'll do nothing */

	T->Height = std::max(Height(T->Left), Height(T->Right)) + 1;

	return T;

}

 

你可能感兴趣的:(实现)