算法导论-13-3-AVL树

题目:

算法导论-13-3-AVL树_第1张图片

答:

a)一棵高度为h的AVL树中,至少有Fh个结点,其中Fh是第h个斐波那契数

b)AVL的旋转算法见AVL平衡树的旋转

c)

AVLTree.h

#include <iostream>
#include <vector>
using namespace std;

#define NONODE -0x7FFFFFF

struct nodeOfAvl
{
	int key;
	int height;
	nodeOfAvl *pLeftChild;
	nodeOfAvl *pRightChild;
	nodeOfAvl *pParent;
	nodeOfAvl(int k = NONODE):pLeftChild(NULL),pRightChild(NULL),key(k),pParent(NULL),height(1){}
	~nodeOfAvl();
	void visit(vector<int> *pDataVec);
	bool isChildExist(bool leftOrRight);
	nodeOfAvl *getChild(bool leftOrRight);
	void setChild(bool leftOrRight, nodeOfAvl* pChild);
	int getStatus(bool newInsertSide);
	void setHeight();
	bool isChildLeftOrRight();
};

struct CAVLTree
{
	nodeOfAvl *pRootNode;

	CAVLTree():pRootNode(NULL){}
	~CAVLTree();

	vector<int> print();
};

nodeOfAvl* insert(nodeOfAvl *pRootNode, nodeOfAvl *pNewNode);


AVLTree.cpp

#include "AVLTree.h"
#include <queue>
#include <stack>
#include <vector>

#define LEFT 0
#define RIGHT 1

#define BALANCE 5
#define LL 0
#define LR 1
#define RL 2
#define RR 3

int getHeight(nodeOfAvl *pCurrentNode);
bool isChildLeftOrRight();
bool getInsertSide(nodeOfAvl* pRootNode, nodeOfAvl* pNewNode);
nodeOfAvl * rebalance(nodeOfAvl* pRootNode, nodeOfAvl * pNewNode, bool insertSide);

nodeOfAvl::~nodeOfAvl()
{
	if(pLeftChild != NULL)
	{
		delete pLeftChild;
	}
	if(pRightChild != NULL)
	{
		delete pRightChild;
	}
}

void nodeOfAvl::visit(vector<int> *pDataVec)
{
	pDataVec->push_back(key);
}

bool nodeOfAvl::isChildExist(bool leftOrRight)
{
	bool ret = false;
	if(leftOrRight == LEFT && pLeftChild != NULL)
		ret = true;
	if(leftOrRight == RIGHT && pRightChild != NULL)
		ret = true;
	return ret;
}

nodeOfAvl *nodeOfAvl::getChild(bool leftOrRight)
{
	nodeOfAvl *pRet = NULL;
	if(leftOrRight == LEFT)
		pRet = pLeftChild;
	else if(leftOrRight == RIGHT)
		pRet = pRightChild;
	return pRet;
}

void nodeOfAvl::setChild(bool leftOrRight, nodeOfAvl* pChild)
{
	if(leftOrRight == LEFT)
		pLeftChild = pChild;
	else if(leftOrRight == RIGHT)
		pRightChild = pChild;
	if(pChild != NULL)
		pChild->pParent = this;
}

int nodeOfAvl::getStatus(bool newInsertSide)
{
	int ret = BALANCE;
	int heightNoInsert = getHeight(getChild(!newInsertSide));
	int heightWithInsert = getHeight(getChild(newInsertSide));
	if(heightWithInsert - heightNoInsert >= 2)
	{
		ret = newInsertSide << 1;
		if(getChild(newInsertSide)->isChildExist(LEFT) == false)
			ret = ret | 1;
	}
	else
	{
		ret = BALANCE;
	}
	return ret;
}

void nodeOfAvl::setHeight()
{
	height = max(getHeight(pLeftChild), getHeight(pRightChild)) + 1;
}

bool nodeOfAvl::isChildLeftOrRight()
{
	//assert(pParentNode != NULL);
	bool ret = LEFT;
	if(this == pParent->pLeftChild)
		ret = LEFT;
	else if(this == pParent->pRightChild)
		ret = RIGHT;
	return ret;
}
CAVLTree::~CAVLTree()
{
	if(pRootNode != NULL)
		delete pRootNode;
	pRootNode = NULL;
}

int Height(nodeOfAvl *pCurrent)
{
	if(pCurrent == NULL)
		return 0;
	return pCurrent->height;
}

nodeOfAvl* rotate(nodeOfAvl *pParent, nodeOfAvl *pChild, bool rotateDirection)
{
	//assert(pChild->pParent == pParent && pChild->isChildLeftOrRight() != rotationDirection);
	nodeOfAvl *pGrandChild = pChild->getChild(rotateDirection);
	pParent->setChild(!rotateDirection, pGrandChild);
	pChild->setChild(rotateDirection, pParent);

	pParent->setHeight();
	pChild->setHeight();
	return pChild;
}

nodeOfAvl* insert(nodeOfAvl *pRootNode, nodeOfAvl *pNewNode)
{
	nodeOfAvl *pRetNewRoot = NULL;

	if(pRootNode == NULL)
		return pNewNode;

	bool nextSide = getInsertSide(pRootNode, pNewNode);
	nodeOfAvl *pNewRoot = pRootNode->getChild(nextSide);
	pNewRoot = insert(pNewRoot, pNewNode);
	pRootNode->setChild(nextSide, pNewRoot);

	pRetNewRoot = rebalance(pRootNode, pNewRoot, nextSide);
}

vector<int> CAVLTree::print()
{
	vector<int> retDataVec;
	if(pRootNode == NULL)
		return retDataVec;

	queue<nodeOfAvl *> nodeQueue;

	nodeQueue.push(pRootNode);
	int existNodeCnt = 1;

	nodeOfAvl *pNullNode;
	while(nodeQueue.empty() == false && existNodeCnt > 0)
	{
		nodeOfAvl *pCurrentNode = nodeQueue.front();
		nodeQueue.pop();

		if(pCurrentNode == NULL)
		{
			delete pCurrentNode;
			nodeQueue.push(new nodeOfAvl);
			nodeQueue.push(new nodeOfAvl);
		}
		else
		{
			existNodeCnt--;
			retDataVec.push_back(pCurrentNode->key);
			if(pCurrentNode->isChildExist(LEFT) == true)
			{
				existNodeCnt++;
				nodeQueue.push(pCurrentNode->pLeftChild);
			}
			else if(pCurrentNode->height > 1)
				nodeQueue.push(new nodeOfAvl);
			if(pCurrentNode->isChildExist(RIGHT) == true)
			{
				existNodeCnt++;
				nodeQueue.push(pCurrentNode->pRightChild);
			}
			else if(pCurrentNode->height > 1)
				nodeQueue.push(new nodeOfAvl);
		}
	}
	while(nodeQueue.empty() == false)
	{
		nodeOfAvl *pCurrentNode = nodeQueue.front();
		delete pCurrentNode;
		nodeQueue.pop();
	}
	return retDataVec;
}

int getHeight(nodeOfAvl *pCurrentNode)
{
	int ret = 0;
	if(pCurrentNode != NULL)
		ret = pCurrentNode->height;
	return ret;
}

bool getInsertSide(nodeOfAvl* pRootNode, nodeOfAvl* pNewNode)
{
	bool retSide = LEFT;
	if(pNewNode->key < pRootNode->key)
		retSide = LEFT;
	else if(pNewNode->key > pRootNode->key)
		retSide = RIGHT;
	return retSide;
}

nodeOfAvl * rebalance(nodeOfAvl* pRootNode, nodeOfAvl * pNewRoot, bool insertSide)
{
	int status = pRootNode->getStatus(insertSide);
	nodeOfAvl* pRetNewRoot = NULL;

	switch (status)
	{
	case BALANCE:
		pRootNode->setHeight();
		pRetNewRoot = pRootNode;
		break;
	case LL:
		pRetNewRoot = rotate(pRootNode, pNewRoot, RIGHT);
		break;
	case LR:
		pNewRoot = rotate(pNewRoot, pNewRoot->pRightChild, LEFT);
		pRetNewRoot = rotate(pRootNode, pNewRoot, RIGHT);
		break;
	case RL:
		pNewRoot = rotate(pNewRoot, pNewRoot->pLeftChild, RIGHT);
		pRetNewRoot = rotate(pRootNode, pNewRoot, LEFT);
		break;
	case RR:
		pRetNewRoot = rotate(pRootNode, pNewRoot, LEFT);
		break;
	}
	return pRetNewRoot;
}


 

你可能感兴趣的:(算法导论-13-3-AVL树)