AVL树的一些实现

包含,插入,单旋转,双旋转,以及每次都要想好久的,除了结点里指针的其余的指针都想不清楚......又想了一遍......

//AVL,二叉平衡树,任何一个结点,左右子树的高度差都不大于1的二叉搜索树
template <typename Comparable>
struct AvlNode
{
	Comparable element;
	AvlNode *left;
	AvlNode *right;
	int height;

	AvlNode(const Comparable & theElement, AvlNode *lt, AvlNode *rt, int h = 0) :element(theElement), left(lt), right(rt), height(h)
	
	int height(AvlNode *t) const
	{
		return t == NULL ? -1 : t->height;          //AVL中,NULL高度设为1,这样叶子结点就是0了,然后上面的高度就都可以算了
	}

	void insert(const Comparable & x, AvlNode * & t)     //把x插入到以t为根结点的树上
	{
		if (t == NULL)
			t = new AvlNode(x, NULL.NULL);
		else if (x < t->element)
		{
			insert(x, t->left);    //插入
			if (height(t->left) - height(t->right) == 2)    //调整
			{
				if (x < t->left->element)
					rotateWithLeftChild(t);          //值小于t->left的,单旋转
				else
					DoubleWithLeftChild(t);          //值介于t和t->left之间,双旋转
			}
		}
		else if (x > t->element)
		{
			insert(x, t->right);    //插入
			if (height(t->right) - height(t->left) == 2)    //调整
			{
				if (x > t->right->element)
					rotateWithRightChild(t);          //值小于t->left的,单旋转
				else
					DoubleWithRightChild(t);          //值介于t和t->left之间,双旋转
			}
		}
		else;                     //什么都不干
		t->height = max(height(t->left), height(t->right)) + 1;     //计算树的新高度
		
	}


	//一共四种旋转,原理上只有两类(LL,RR;LR,RL),但是代码是4类,这里实现两类(LL,LR),左右是对称的。(LL和RR,用单旋转,LR和RL,用双旋转,不过用单旋转还是双旋转,就按照代码里写的判定吧)
	//这个单旋转的逻辑,参见《数据结构与算法分析C++描述第三版》,双旋转感觉它说的不好,但是看它给的代码实现加上嵌在代码实现里的例子,就很明白了
	void rotateWithLeftChild(AvlNode * & k2)               //还是那个*和Node的问题,k2就理解成拎着结点的小棍棍,第一行是再弄一个小棍棍拎着k2->left这个小棍棍拎着的结点,叫做k1;然后最后的一行,意思是让k2不要拎着现在的结点了,让它拎着新的根结点
	{
		AvlNode *k1 = k2->left;
		k2->left = k1->right;
		k1->right = k2;
		k2->height = max(height(k2->left), height(k2->right)) + 1;
		k1->height = max(height(k1->left), k2->height) + 1;
		k2 = k1;
	}

	void DoubleWithLeftChild(AvlNode * & k3)
	{
		rotateWithRightChild(k3->left);
		rotateWithLeftChild(k3);
	}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值