C C++最新【算法学习】AVL平衡二叉搜索树原理及各项操作编程实现(C++,2024最新爱奇艺C C++社招面试题目

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

这个是需要判断当前根节点是否仍然满足平衡条件,

如果满足平衡条件,只需要更新当前根节点T的高度信息。

否则,需要进行旋转调整:

如果T的左子节点的左子树的高度大于T的左子节点的右子树的高度,进行相应的单旋转。否则进行双旋转。

(3)要删除的节点元素值大于当前根节点T值,在右子树中进行删除。

过程与上述步骤类似。

具体请看代码。

这里仅列出我编程实现的代码,如发现bug,还有包涵和指正!

AVLTree.h:

#ifndef AVLTREE_H_INCLUDED
#define AVLTREE_H_INCLUDED

//AVL树数据结构定义
typedef int ElementType;//AVL数节点包含数据类型

//树节点
typedef struct AVLNode{
	ElementType element;//节点包含的数据元素
	AVLNode *left;//节点左子树
	AVLNode *right;//节点右子树
	int height;//节点所在的高度
}*AVLTree;

//AVL tree类封装
class CAVLTree{
private:
	//供内部调用的函数
	int getHeight(AVLTree);//求得树的高度

	void setHeight(AVLTree,int);//设置节点的高度值

	//单旋转:向右旋转
	AVLTree SingleRightRotate(AVLTree);
	//单旋转:向左旋转
	AVLTree SingleLeftRotate(AVLTree);
	//双旋转:左右
	AVLTree DoubleRightRotate(AVLTree);
	//双旋转:右左
	AVLTree DoubleLeftRotate(AVLTree);

public:
	//默认构造函数
	CAVLTree();
	//析构函数
	~CAVLTree();
	//创建AVL树
	void createAVLTree(ElementType *data,int n);
	//插入节点
	AVLTree insertNode(AVLTree T,ElementType val);
	//删除树中元素值等于某值的节点
	AVLTree deleteNode(AVLTree T,const ElementType val);
	//搜寻元素值等于某值的节点
	AVLTree searchNode(AVLTree,ElementType);
	//前序遍历输出树
	void preOrder(AVLTree T);
	//得到树中的元素值最大的节点
	AVLTree getMaxNode(AVLTree);
	//得到树中的元素值最小的那个节点
	AVLTree getMinNode(AVLTree);

	AVLTree T;
};

#endif // AVLTREE_H_INCLUDED

AVLTree.cpp:

#include "AVLTree.h"

#include <iostream>
#include <cmath>
#include <cassert>

using namespace std;

CAVLTree::CAVLTree()
{
	T = NULL;
}

CAVLTree::~CAVLTree()
{
	//if(T)
	//{
	//	if(NULL == T->left && NULL == T->right)
	//		delete T;
	//	else{
	//		delete T->left;
	//		delete T->right;
	//	}
	//}
	deleteTree(T);
}

//依据各元素的数据值,创建AVL树
void CAVLTree::createAVLTree(ElementType *data,int n)
{
	if (T)
	{
		cout << "The AVL Tree has been created" << endl;

		return;
	}

	if(!n)//元素序列为空
	{
		T = NULL;
		return;
	}

	for(int i = 0;i < n;++i)
	{
		T = insertNode(T,*(data + i));
	}

	return;
}

AVLTree CAVLTree::insertNode(AVLTree T,ElementType val)
{
	AVLNode *pNewNode = new AVLNode;
	pNewNode->element = val;
	pNewNode->left = NULL;
	pNewNode->right = NULL;
	pNewNode->height = 1;//新节点一定被插入在空节点的位置

	if(NULL == T)
	{
		T = pNewNode;
		return T;
	}

	//需要插入节点的树非空
	//插入的元素已经存在于树中,不符合要求
	if (val == T->element)
	{
		cout << "元素中有重复,构建AVL树失败!" << endl;
		return T;
	}
	//要插入的值小于根节点的值,将其插入左子树中
	if(val < T->element)
	{
		//将其插入根节点的左子树中
		T->left = insertNode(T->left,val);
		//判断平衡条件是否仍然满足
		if(getHeight(T->left) - getHeight(T->right) > 1)
		{
			//分两种情况进行旋转操作
			//插入点位于T的左子结点的左子树
			if(val < T->left->element)
				//实施单旋转-右旋转
				T = SingleRightRotate(T);
			else
				//插入点位于T的左子结点的右子树,实施双右旋转
				T = DoubleRightRotate(T);
		}
	}
	//要插入的值大于根节点的值,将其插入右子树中
	if(val > T->element)
	{
		T->right = insertNode(T->right,val);
		//判断平衡条件是否仍然满足
		if(getHeight(T->right) - getHeight(T->left) > 1)
		{
			//节点插入到T的右子节点的右子树中
			if(val > T->right->element)
				//实施单旋转-左旋转
				T = SingleLeftRotate(T);
			else
				//节点插入到T的右子节点的左子树上
				//实施双旋转-左旋转
				T = DoubleLeftRotate(T);
		}
	}

	//更新节点的height值
	setHeight(T,max(getHeight(T->left),getHeight(T->right)) + 1);

	return T;
}

AVLTree CAVLTree::deleteNode(AVLTree T,const ElementType val)
{
	if (!T)
	{
		cout << "The tree is NULL, delete failed" << endl;
		return T;
	}

	AVLTree searchedNode = searchNode(T,val);
	//没有找到相应的节点,删除失败
	if (!searchedNode)
	{
		cout << "Cann't find the node to delete " << val << endl;
		return T;
	} 
	
	//找到了需要删除的节点
	//需要删除的节点就是当前子树的根节点
	if (val == T->element)
	{
		//左右子树都非空
		if (T->left && T->right)
		{
			//在高度更大的那个子树上进行删除操作
			if (getHeight(T->left) > getHeight(T->right))
			{
				//左子树高度大,删除左子树中元素值最大的那个节点,同时将其值赋值给根节点
				T->element = getMaxNode(T->left)->element;
				T->left = deleteNode(T->left,T->element);
			}
			else{
				//删除右子树中元素值最小的那个节点,同时将其值赋值给根节点
				T->element = getMinNode(T->right)->element;
				T->right = deleteNode(T->right,T->element);
			}
		}
		else{
			//左右子树中有一个不为空,那个直接用需要被删除的节点的子节点替换之即可
			AVLTree oldNode = T;
			T = (T->left ? T->left : T->right);
			delete oldNode;//释放节点所占的空间
			oldNode = NULL;
		}
	}
	else if (val < T->element)//要删除的节点在左子树中
	{
		//在左子树中进行递归删除
		T->left = deleteNode(T->left,val);
		//判断是否仍然满足平衡条件
		if (getHeight(T->right) - getHeight(T->left) > 1)
		{
			if (T->right->left > T->right->right)
			{
				//左双旋转
				T = DoubleLeftRotate(T);
			}
			else//进行左单旋转
				T = SingleLeftRotate(T);
		}
		else
			//满足平衡条件,需要更新高度信息
			T->height = max(getHeight(T->left),getHeight(T->right)) + 1;
	}
	else//需要删除的节点在右子树中
	{
		T->right = deleteNode(T->right,val);
		//判断是否满足平衡条件
		if (getHeight(T->left) - getHeight(T->right) > 1)
		{
			if(getHeight(T->left->right) > getHeight(T->left->left))
				//右双旋转
				T = DoubleRightRotate(T);
			else
				//右单旋转
				T = SingleRightRotate(T);
		}
		else
			//只需调整高度即可
			T->height = max(getHeight(T->left),getHeight(T->right)) + 1;
	}

	return T;
}

AVLTree CAVLTree::searchNode(AVLTree T,ElementType val)
{
	if (!T)
	{
		return NULL;
	}

	//搜索到
	if (val == T->element)
	{
		return T;
	}
	else if (val < T->element)
	{
		//在左子树中搜索
		return searchNode(T->left,val);
	}
	else
	{
		//在右子树中搜索
		return searchNode(T->right,val);
	}
}

void CAVLTree::preOrder(AVLTree T)
{
	if(!T)
		cout << "NULL ";
	else
	{
		cout << T->element << " ";
		preOrder(T->left);
		preOrder(T->right);
	}
}

AVLTree CAVLTree::getMaxNode(AVLTree T)
{
	if (!T)//树为空
	{
		return NULL;
	}

	AVLTree tempNode = T;
	//向右搜寻直至右子节点为NULL
	while(tempNode->right)
	{
		tempNode = tempNode->right;
	}

	return tempNode;
}

AVLTree CAVLTree::getMinNode(AVLTree T)
{
	if (!T)//树为空
	{
		return NULL;
	}

	AVLTree tempNode = T;
	//向左搜寻直至左子结点为NULL
	while(tempNode->left)
	{
		tempNode = tempNode->left;
	}

	return tempNode;
}

int CAVLTree::getHeight(AVLTree T)
{
	return (T == NULL) ? 0 : (T->height);
}

void CAVLTree::setHeight(AVLTree T,int height)
{
	T->height = height;
}

//左左外侧插入导致的不平衡,采用单旋转-右旋转进行修正
//参数解释:
//T:指向因某种操作失去平衡的最小子树根节点
AVLTree CAVLTree::SingleRightRotate(AVLTree T)
{
	AVLTree xPNode = T;
	AVLTree yPNode = T->left;
	xPNode->left = yPNode->right;//更改原根节点的左子树
	yPNode->right = xPNode;//更改原根节点左孩子的右子树

	//更新进行了旋转操作的节点的高度
	xPNode->height = max(getHeight(xPNode->left),getHeight(xPNode->right)) + 1;
	yPNode->height = max(getHeight(yPNode->left),getHeight(yPNode->right)) + 1;

	//原根节点的左孩子节点成为新的根节点
	return yPNode;
}

//右右外侧插入导致的不平衡,采用单旋转-左旋转进行修正
//参数解释:
//T:指向因某种操作失去平衡的最小子树根节点
AVLTree CAVLTree::SingleLeftRotate(AVLTree T)
{
	AVLTree xPNode = T;
	AVLTree yPNode = T->right;


![img](https://img-blog.csdnimg.cn/img_convert/d38795a91568d00e9d9a5c0acb22ed34.png)
![img](https://img-blog.csdnimg.cn/img_convert/471cbc1060b915b05ae8f0c15c7806a6.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

T:指向因某种操作失去平衡的最小子树根节点
AVLTree CAVLTree::SingleLeftRotate(AVLTree T)
{
	AVLTree xPNode = T;
	AVLTree yPNode = T->right;


[外链图片转存中...(img-kLqbzCUd-1715726594188)]
[外链图片转存中...(img-20XyNrdB-1715726594188)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值