AVL的C++实现

AVL树是平衡的二叉查找树。也是高度平衡的二叉查找树。每个节点的左子树的高度与右子树的高度的差的绝对值小于等于1.

AVL树的基本操作包括:

  • 首先包括旋转操作:左旋(逆时针),右旋(顺时针),左—右旋转(先左旋,后右旋),右—左旋转(先右旋,后左旋)。
  1. 右旋

void RotaeRR(AvlTree* &avl) {
	if (!avl)
		return;
	else {
		auto ptr = avl->lchild;
		avl->lchild = ptr->rchild;
		ptr->rchild = avl;
		avl = ptr;

		avl->height = max(Getheight(avl->lchild), Getheight(avl->rchild)) + 1;
		ptr->height = max(Getheight(ptr->lchild), avl->height) + 1;
	}
}

左旋和右旋是镜像对称的,所以不在讨论。

2.左—右旋转

void RotaeLR(AvlTree* &avl) {
	if (!avl)
		return;
	else {
		RotaeLL(avl->rchild);
		RotaeRR(avl);
	}
}
  • 节点的高度。
int Getheight(AvlTree* &avl) {
	if (avl == nullptr)
		return -1;
	else
		return avl->height;
}

int max(int a, int b) {
	return a > b ? a : b;
}
  • 插入操作。AVL树的插入操作和Bst树的插入操作很相似,无非就是在插入中要通过旋转保持树的平衡性

 第三种情况和第四种情况关于上面两种情况镜像对称

void Insert(AvlTree* &avl, ElemType X) {
	int rightheight = 0, leftheight = 0;
	if (!avl) {
		avl = new AvlTree;
		avl->element = X;
		avl->height = 0;
		avl->lchild = avl->rchild = nullptr;
	}
	else {
		if (avl->element > X) {
			Insert(avl->lchild, X);
			rightheight = Getheight(avl->rchild);
			leftheight = Getheight(avl->lchild);
			if ((leftheight - rightheight) > 1) {
				if (avl->lchild->element > X)
					RotaeRR(avl);
				else
					RotaeLR(avl);
			}
		}
		else if (avl->element < X) {
			Insert(avl->rchild, X);
			rightheight = Getheight(avl->rchild);
			leftheight = Getheight(avl->lchild);
			if ((rightheight - leftheight) > 1) {
				if (avl->rchild->element < X)
					RotaeLL(avl);
				else
					RotaeRL(avl);
			}
		}
	}

	avl->height = max(Getheight(avl->lchild), Getheight(avl->rchild)) + 1;

}
  • 删除操作。AVL树的删除操作与Bst树比较相似,无非就是在删除中要通过旋转保持树的平衡性。

void Delete(AvlTree* &avl, ElemType X) {
	int rightheight = 0, leftheight = 0;
	int rightheight_ = 0, leftheight_ = 0;
	AvlTree* temp = nullptr;
	if (!avl)
		return;
	else if (avl->element > X) {
		Delete(avl->lchild, X);
		rightheight = Getheight(avl->rchild);
		leftheight = Getheight(avl->lchild);
		if ((rightheight - leftheight) > 1) {
			rightheight_ = Getheight(avl->rchild->rchild);
			leftheight_ = Getheight(avl->rchild->lchild);
			if (rightheight_ > leftheight_)
				RotaeLL(avl);
			else
				RotaeRL(avl);
		}
	}
	else if (avl->element < X) {
		Delete(avl->rchild, X);
		rightheight = Getheight(avl->rchild);
		leftheight = Getheight(avl->lchild);
		if ((leftheight - rightheight) > 1) {
			rightheight_ = Getheight(avl->lchild->rchild);
			leftheight_ = Getheight(avl->lchild->lchild);

			if (rightheight_ < leftheight_)
				RotaeRR(avl);
			else
				RotaeLR(avl);
		}
	}
	else if (avl->element == X) {
		temp = avl;
		if (avl->lchild != nullptr && avl->rchild != nullptr) {
			temp = FindMin(avl->rchild);
			avl->element = temp->element;
			Delete(avl->rchild, avl->element);
		}
		else if (avl->lchild == nullptr)
			avl = avl->rchild;
		else if (avl->rchild == nullptr)
			avl = avl->lchild;
		else
			delete temp;
	}
}

 第三种情况和第四种情况与上面情况镜像对称。

AVL树的上面几种操作比较难理解,其他都相对比较简单。完整代码如下:

#include<iostream>
#include<vector>
typedef struct TreeNode  AvlTree;
typedef int    ElemType;
struct TreeNode {
	ElemType   element;
	AvlTree*   lchild;
	AvlTree*   rchild;
	int        height;
};
int Getheight(AvlTree* &avl) {
	if (avl == nullptr)
		return -1;
	else
		return avl->height;
}

int max(int a, int b) {
	return a > b ? a : b;
}

AvlTree* Find(AvlTree* &avl, ElemType X) {
	if (!avl)
		return nullptr;
	else if (avl->element > X)
		avl->lchild = Find(avl->lchild, X);
	else if (avl->element < X)
		avl->rchild = Find(avl->rchild, X);
	else if (avl->element == X)
		return avl;
}

AvlTree* FindMax(AvlTree* &avl) {
	if (!avl) {
		while (avl->rchild != nullptr)
			avl = avl->rchild;
	}

	return avl;
}

AvlTree* FindMin(AvlTree* &avl) {
	if (!avl) {
		while (avl->lchild != nullptr)
			avl = avl->lchild;
	}

	return avl;
}

void RotaeRR(AvlTree* &avl) {
	if (!avl)
		return;
	else {
		auto ptr = avl->lchild;
		avl->lchild = ptr->rchild;
		ptr->rchild = avl;
		avl = ptr;

		avl->height = max(Getheight(avl->lchild), Getheight(avl->rchild)) + 1;
		ptr->height = max(Getheight(ptr->lchild), avl->height) + 1;
	}
}

void RotaeLL(AvlTree* &avl) {
	if (!avl)
		return;
	else {
		auto ptr = avl->rchild;
		avl->rchild = ptr->lchild;
		ptr->lchild = avl;
		avl = ptr;

		avl->height = max(Getheight(avl->lchild), Getheight(avl->rchild)) + 1;
		ptr->height = max(Getheight(ptr->rchild), avl->height) + 1;
	}
}

void RotaeRL(AvlTree* &avl) {
	if (!avl)
		return;
	else {
		RotaeRR(avl->lchild);
		RotaeLL(avl);
	}
}

void RotaeLR(AvlTree* &avl) {
	if (!avl)
		return;
	else {
		RotaeLL(avl->rchild);
		RotaeRR(avl);
	}
}

void Insert(AvlTree* &avl, ElemType X) {
	int rightheight = 0, leftheight = 0;
	if (!avl) {
		avl = new AvlTree;
		avl->element = X;
		avl->height = 0;
		avl->lchild = avl->rchild = nullptr;
	}
	else {
		if (avl->element > X) {
			Insert(avl->lchild, X);
			rightheight = Getheight(avl->rchild);
			leftheight = Getheight(avl->lchild);
			if ((leftheight - rightheight) > 1) {
				if (avl->lchild->element > X)
					RotaeRR(avl);
				else
					RotaeLR(avl);
			}
		}
		else if (avl->element < X) {
			Insert(avl->rchild, X);
			rightheight = Getheight(avl->rchild);
			leftheight = Getheight(avl->lchild);
			if ((rightheight - leftheight) > 1) {
				if (avl->rchild->element < X)
					RotaeLL(avl);
				else
					RotaeRL(avl);
			}
		}
	}

	avl->height = max(Getheight(avl->lchild), Getheight(avl->rchild)) + 1;

}

void Delete(AvlTree* &avl, ElemType X) {
	int rightheight = 0, leftheight = 0;
	int rightheight_ = 0, leftheight_ = 0;
	AvlTree* temp = nullptr;
	if (!avl)
		return;
	else if (avl->element > X) {
		Delete(avl->lchild, X);
		rightheight = Getheight(avl->rchild);
		leftheight = Getheight(avl->lchild);
		if ((rightheight - leftheight) > 1) {
			rightheight_ = Getheight(avl->rchild->rchild);
			leftheight_ = Getheight(avl->rchild->lchild);
			if (rightheight_ > leftheight_)
				RotaeLL(avl);
			else
				RotaeRL(avl);
		}
	}
	else if (avl->element < X) {
		Delete(avl->rchild, X);
		rightheight = Getheight(avl->rchild);
		leftheight = Getheight(avl->lchild);
		if ((leftheight - rightheight) > 1) {
			rightheight_ = Getheight(avl->lchild->rchild);
			leftheight_ = Getheight(avl->lchild->lchild);

			if (rightheight_ < leftheight_)
				RotaeRR(avl);
			else
				RotaeLR(avl);
		}
	}
	else if (avl->element == X) {
		temp = avl;
		if (avl->lchild != nullptr && avl->rchild != nullptr) {
			temp = FindMin(avl->rchild);
			avl->element = temp->element;
			Delete(avl->rchild, avl->element);
		}
		else if (avl->lchild == nullptr)
			avl = avl->rchild;
		else if (avl->rchild == nullptr)
			avl = avl->lchild;
		else
			delete temp;
	}
}


void print(AvlTree* &avl) {
	if (!avl)
		return;
	else {
		std::cout << avl->element << "\n";
		print(avl->lchild);
		print(avl->rchild);
	}
}

int main(void)
{
	std::vector<int>vec{ 1,2,3,4,5,6,7,8,9};
	AvlTree* avl = nullptr;
	for (const auto& x : vec) {
		Insert(avl, x);
	}

	print(avl);
	std::cout << "----------------------------------" << "\n";
	std::cout << "delete a elem: 5" << "\n";
	Delete(avl, 5);
	print(avl);
	

}

 

发布了50 篇原创文章 · 获赞 11 · 访问量 4094

猜你喜欢

转载自blog.csdn.net/qq_43145594/article/details/101078353