04-树5 Root of AVL Tree(C++)

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.

04-树5 Root of AVL Tree(C++)_第1张图片

04-树5 Root of AVL Tree(C++)_第2张图片

04-树5 Root of AVL Tree(C++)_第3张图片

04-树5 Root of AVL Tree(C++)_第4张图片

Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤20) which is the total number of keys to be inserted. Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the root of the resulting AVL tree in one line.

Sample Input 1:

5
88 70 61 96 120

Sample Output 1:

70

Sample Input 2:

7
88 70 61 96 120 90 65

Sample Output 2:

88

code 

# include 
# include 
# include 

# define geth(x) (int)(x ? x->high :(int)( -1) )
# define max(x, y) (x>y?x:y)
# define BF(x) geth(x->left) - geth(x->right)

struct Node {
	int data, high;
	Node * parent, *left, *right;

	Node(int d, Node * p):data(d), parent(p), left(NULL), right(NULL), high(0){}
	void updh() { high = max(geth(left), geth(right) )+1;}

};

Node * tallerChild(Node * x)
{
	return  (BF(x) > 0) ? x->left : x->right;
}

struct AVL {
	Node * root;
	Node * _hot;
	AVL():root(NULL){}
	Node * & search(int val) { _hot = NULL; return searchIn(val, root, _hot); }

	Node * & searchIn(int val, Node * & rt, Node * & hot)
	{
		if (!rt || rt->data == val) return rt;
		hot = rt;
		return searchIn(val, rt->data < val ? rt->right : rt->left, hot);
	}

	Node * & fromParentTo(Node * p)
	{
		if (p == root) return root;
		
		if (p == p->parent->left) return p->parent->left;
		else return p->parent->right;
	}
	void insert(int val)
	{
		Node * & X = search(val);
		X = new Node(val, _hot);

		for (Node * p = _hot; p; p = p->parent)
		{
			if (BF(p) > 1 || BF(p) < -1)
			{
				Node * & tmp = fromParentTo(p);
				tmp = roatAt(tallerChild(tallerChild(p)));
			}
			else p->updh();
		}
	}

	Node * roatAt(Node * v)
	{
		Node * p = v->parent, *g = p->parent;
		Node * a, *b, *c, *T1, *T2, *T3, *T4;
		if (p == g->left && v == p->left)
		{
			a = v; b = p; c = g;
			T1 = v->left; T2 = v->right; T3 = p->right; T4 = g->right;
		}
		else if (p == g->left && v == p->right)
		{
			a = p; b = v; c = g;
			T1 = p->left; T2 = v->left; T3 = v->right; T4 = g->right;

		}
		else if (p == g->right && v == p->left)
		{
			a = g; b = v; c = p;
			T1 = g->left; T2 = v->left; T3 = v->right; T4 = p->right;
		}
		else
		{
			a = g; b = p; c = v;
			T1 = g->left; T2 = p->left; T3 = v->left; T4 = v->right;
		}
		b->parent = g->parent; 
		return connect34(a, b, c, T1, T2, T3, T4);
	}

	Node * connect34(Node * a, Node * b, Node * c, Node * T1, Node * T2, Node * T3, Node * T4)
	{
		b->left = a;  b->right = c;
		a->left = T1; a->right = T2;
		c->left = T3; c->right = T4;

		a->parent = b; c->parent = b;

		if (T1) T1->parent = a;
		if (T2) T2->parent = a;
		if (T3) T3->parent = c;
		if (T4) T4->parent = c;
		a->updh(); b->updh(); c->updh();
		return b;
	}
};

int main(void)
{
	AVL T;
	int n;
	scanf("%d", &n);
	while (n--)
	{
		int tmp;
		scanf("%d", &tmp);
		T.insert(tmp);
	}
	printf("%d\n", T.root->data);
	return 0;
}

 

你可能感兴趣的:(ZJU数据结构,数据结构)