题目:
答:
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;
}