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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章