#数据结构与算法学习笔记#PTA13:平衡二叉树AVL Tree(C/C++)

2018.5.2

平衡二叉树(AVL Tree)是任意结点平衡因子BF(左右子树左右高度差)≤1的二叉搜索树。要想建成AVL树,需要在每一个结点插入时进行判断和调整。调整的方法有四种(左左单旋、右右单旋、左右双旋、右左双旋),四种方式分别根据结点插入时的相对结构判断,如下图Figure1的情况为左左单旋调整情况。

本题要求根据输入顺序建一棵AVL树,并且返回其根节点。思路就是AVL树的基本操作了。需要注意的是,给树的每个结点加一个参数代表树高,当左右子树高度差为2时进行调整,每次对树结构调整后也需要对树高值进行调整。具体操作详见代码。


题目描述:

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.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.




实现代码:

// Root_of_AVLTree.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

using namespace std;

typedef int ElementType;
class AVLNode {
public:

	AVLNode() {

	}

	AVLNode(ElementType data, int Height = 0)
		:data(data),left(NULL), right(NULL),Height(Height){
	}

	ElementType data;
	AVLNode* left;
	AVLNode* right;
	int Height;		//树高
};
typedef AVLNode* AVLTree;


int GetHeight(AVLTree A);
int Max(int a, int b);
AVLTree SingleLeftRotation(AVLTree A);				//左左单旋
AVLTree SingleRightRotation(AVLTree A);				//右右单旋
AVLTree DoubleLeftRightRotation(AVLTree A);			//左右双旋
AVLTree DoubleRightLeftRotation(AVLTree A);			//右左双旋
AVLTree Insert(AVLTree tree, ElementType element);	



int main()
{
	int num;
	cin >> num;
	
	AVLTree tree = NULL;
	for (int i = 0; i < num; i++) {
		int element;
		cin >> element;
		tree = Insert(tree, element);
	}

	cout << tree->data;

	system("pause");
    return 0;
}

int GetHeight(AVLTree A) {
  
	if (A)
		return Max(GetHeight(A->left), GetHeight(A->right)) + 1;
	else
		return 0;

}

int Max(int a, int b) {
	return a > b ? a : b;
}

//左左单旋
AVLTree SingleLeftRotation(AVLTree A) {
	//注意A必须有一个左子结点B
	//将A与B做左单旋,更新A与B的高度,返回新的结点B
	AVLTree B = A->left;
	A->left = B->right;
	B->right = A;

	A->Height = Max(GetHeight(A->left), GetHeight(B->right)) + 1;
	B->Height = Max(GetHeight(B->left), A->Height) + 1;

	return B;
}

//右右单旋
AVLTree SingleRightRotation(AVLTree A) {
	//注意A必须有一个右子结点B
	//将A与B做右单旋,更新A与B的高度,返回新的结点B
	AVLTree B = A->right;
	A->right = B->left;
	B->left = A;

	A->Height = Max(GetHeight(A->right), GetHeight(B->left)) + 1;
	B->Height = Max(GetHeight(B->right), A->Height) + 1;

	return B;
}

//左右双旋
AVLTree DoubleLeftRightRotation(AVLTree A) {
	//A必须有一个左子结点B,且B必须有一个右子节点C
	//将A、B与C做两次单旋,返回新的根节点C

	//将B(A->left)与C做右右单旋,将C作为根节点返回给A左子树
	A->left = SingleRightRotation(A->left);
	//将A与C做左左单旋,将C作为根节点返回
	return SingleLeftRotation(A);

}

//右左双旋
AVLTree DoubleRightLeftRotation(AVLTree A) {
	//A必须有一个右子结点B,且B必须有一个左子节点C
	//将A、B与C做两次单旋,返回新的根节点C

	//将B(A->right)与C做左左单旋,将C作为根节点返回给A左子树
	A->right = SingleLeftRotation(A->right);
	//将A与C做右右单旋,将C作为根节点返回
	return SingleRightRotation(A);

}

AVLTree Insert(AVLTree tree, ElementType element) {
	//若树为空,则新建一个结点
	if (!tree) {
		tree = new AVLNode(element);
	}
	//若元素值大于根节点
	else if (element < tree->data) {
		//递归插入tree的左子树
		tree->left = Insert(tree->left, element);
		//如果需要左旋
		if (GetHeight(tree->left) - GetHeight(tree->right) == 2) {
			//左左单旋
			if (element < tree->left->data) {
				tree = SingleLeftRotation(tree);
			}
			//左右双旋
			else {
				tree = DoubleLeftRightRotation(tree);
			}
		}
	}
	//若元素值小于根节点
	else if (element > tree->data) {
		//递归插入tree的右子树
		tree->right = Insert(tree->right, element);
		//如果需要右旋
		if (GetHeight(tree->right) - GetHeight(tree->left) == 2) {
			//右右单旋
			if (element > tree->right->data) {
				tree = SingleRightRotation(tree);
			}
			//右左双旋
			else {
				tree = DoubleRightLeftRotation(tree);
			}
		}
	}

	//更新树高
	tree->Height = Max(GetHeight(tree->left), GetHeight(tree->right)) + 1;

	return tree;
}


猜你喜欢

转载自blog.csdn.net/qq_20304723/article/details/80178877
今日推荐