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