#pragma once
#include <string.h>
#include <stdlib.h>
#pragma pack(1)
template<typename ValType>
class AVL_NODE {
private:
static const int MAX_VALUE_SIZE = 1024;
public:
AVL_NODE* left;
AVL_NODE* right;
unsigned int nodeHeight : 8;
unsigned int nodeCite : 24;
ValType value;
AVL_NODE(ValType _value) : left(NULL), right(NULL), nodeHeight(1), nodeCite(1), value(_value) {}
static AVL_NODE* newAvlNode(ValType* value, int valueSize)
{
if (!value || valueSize < 1 || valueSize > MAX_VALUE_SIZE) return NULL;
AVL_NODE* newNode = (AVL_NODE*)malloc(sizeof(AVL_NODE) - sizeof(ValType) + valueSize);
if (!newNode) return NULL;
newNode->left = newNode->right = NULL;
newNode->nodeCite = newNode->nodeHeight = 1;
memcpy(&newNode->value, value, valueSize);
return newNode;
}
};
#pragma pack()
#pragma once
#include "avlNode.h"
template<typename ValType>
class Avl {
public:
typedef AVL_NODE<ValType> AVL_NODE, * PAVL_NODE;
Avl();
~Avl();
PAVL_NODE insertValue(ValType* value, int valueSize);
void deleteValue(ValType* value);
unsigned int getTreeHeight();
unsigned int getNodeCount();
private:
PAVL_NODE root;
unsigned int nodeCount;
unsigned int getNodeHeight(PAVL_NODE node);
int cmpValue(ValType* thisValue, ValType* otherValue);
int getBalanceFactor(PAVL_NODE node);
void llRotate(PAVL_NODE& n);
void rrRotate(PAVL_NODE& n);
void lrRotate(PAVL_NODE& n);
void rlRotate(PAVL_NODE& n);
void adjustBalance(PAVL_NODE& root);
void insertValue(PAVL_NODE& root, ValType* value, int valueSize, PAVL_NODE& newNode);
void deleteValue(PAVL_NODE& root, ValType* value, bool isReal);
void destroyTree(PAVL_NODE& root);
};
template<typename ValType>
inline Avl<ValType>::Avl()
{
root = NULL;
nodeCount = 0;
}
template<typename ValType>
inline Avl<ValType>::~Avl()
{
destroyTree(root);
nodeCount = 0;
}
template<typename ValType>
inline unsigned int Avl<ValType>::getNodeHeight(PAVL_NODE node)
{
if (!node) return 0;
return node->nodeHeight;
}
template<typename ValType>
inline int Avl<ValType>::cmpValue(ValType* thisValue, ValType* otherValue)
{
return *thisValue - *otherValue;
}
template<typename ValType>
inline int Avl<ValType>::getBalanceFactor(PAVL_NODE node)
{
if (!node) return 0;
return (int)getNodeHeight(node->left) - (int)getNodeHeight(node->right);
}
template<typename ValType>
void Avl<ValType>::llRotate(PAVL_NODE& n)
{
PAVL_NODE x = n->left;
n->left = x->right;
x->right = n;
x->nodeHeight = std::max(getNodeHeight(x->left), getNodeHeight(x->right)) + 1;
n->nodeHeight = std::max(getNodeHeight(n->left), getNodeHeight(n->right)) + 1;
n = x;
}
template<typename ValType>
void Avl<ValType>::rrRotate(PAVL_NODE& n)
{
PAVL_NODE x = n->right;
n->right = x->left;
x->left = n;
x->nodeHeight = std::max(getNodeHeight(x->left), getNodeHeight(x->right)) + 1;
n->nodeHeight = std::max(getNodeHeight(n->left), getNodeHeight(n->right)) + 1;
n = x;
}
template<typename ValType>
inline void Avl<ValType>::lrRotate(PAVL_NODE& n)
{
rrRotate(n->left);
llRotate(n);
}
template<typename ValType>
inline void Avl<ValType>::rlRotate(PAVL_NODE& n)
{
llRotate(n->right);
rrRotate(n);
}
template<typename ValType>
void Avl<ValType>::adjustBalance(PAVL_NODE& root)
{
int balanceFactor = getBalanceFactor(root);
if (balanceFactor < -1) {
int rBalanceFactor = getBalanceFactor(root->right);
if (rBalanceFactor <= 0) rrRotate(root);
else rlRotate(root);
}
else if (balanceFactor > 1) {
int lBalanceFactor = getBalanceFactor(root->left);
if (lBalanceFactor >= 0) llRotate(root);
else lrRotate(root);
}
root->nodeHeight = std::max(getNodeHeight(root->left), getNodeHeight(root->right)) + 1;
}
template<typename ValType>
void Avl<ValType>::insertValue(PAVL_NODE& root, ValType* value, int valueSize, PAVL_NODE& newNode)
{
if (root == NULL) {
root = AVL_NODE::newAvlNode(value, valueSize);
newNode = root;
if(newNode) nodeCount++;
}
else {
int cmp = cmpValue(value, &root->value);
if (cmp == 0) {
root->nodeCite++;
newNode = root;
}
else if (cmp > 0) {
insertValue(root->right, value, valueSize, newNode);
adjustBalance(root);
}
else {
insertValue(root->left, value, valueSize, newNode);
adjustBalance(root);
}
}
}
template<typename ValType>
void Avl<ValType>::deleteValue(PAVL_NODE& root, ValType* value, bool isReal)
{
if (root == NULL) return;
int cmp = cmpValue(value, &root->value);
if (cmp < 0) deleteValue(root->left, value, isReal);
else if (cmp > 0) deleteValue(root->right, value, isReal);
else {
if (isReal == true && root->nodeCite > 1) {
root->nodeCite--;
return;
}
if (!(root->left)) {
PAVL_NODE temp = root;
root = root->right;
if (isReal) {
free(temp);
nodeCount--;
}
temp = NULL;
}
else if (!(root->right)) {
PAVL_NODE temp = root;
root = root->left;
if (isReal) {
free(temp);
nodeCount--;
}
temp = NULL;
}
else {
PAVL_NODE p = NULL;
if (getNodeHeight(root->left) >= getNodeHeight(root->right)) {
p = root->left;
while (p->right) p = p->right;
deleteValue(root->left, &p->value, false);
}
else {
p = root->right;
while (p->left) p = p->left;
deleteValue(root->right, &p->value, false);
}
p->left = root->left;
p->right = root->right;
free(root);
root = p;
nodeCount--;
}
}
if (root) adjustBalance(root);
}
template<typename ValType>
void Avl<ValType>::destroyTree(PAVL_NODE& root)
{
if (root) {
destroyTree(root->left);
destroyTree(root->right);
free(root);
root = NULL;
}
}
template<typename ValType>
typename Avl<ValType>::PAVL_NODE Avl<ValType>::insertValue(ValType* value, int valueSize)
{
PAVL_NODE newNode = NULL;
insertValue(root, value, valueSize, newNode);
return newNode;
}
template<typename ValType>
void Avl<ValType>::deleteValue(ValType* value)
{
deleteValue(root, value, true);
}
template<typename ValType>
unsigned int Avl<ValType>::getTreeHeight()
{
if (!root) return 0;
return root->nodeHeight;
}
template<typename ValType>
unsigned int Avl<ValType>::getNodeCount()
{
return nodeCount;
}
转载请注明原文地址:https://blackberry.8miu.com/read-33280.html