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);
	}
};

发布了56 篇原创文章 · 获赞 9 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章