利用VC编译。基本用法是实现你自己的回调函数:
extern int compareKey(int treeID,KEY compared,KEY base);
extern bool releaseKey(int treeID,KEY key);
extern bool releaseValue(int treeID,VALUE value);
然后利用createBtree创建树,利用addNode添加节点。利用deleteNode删除节点。利用findNode查找节点。利Min,Max,NextBigger,nextSmaller遍历,利用ReleaseTree销毁树.
//Btree.h
#define KEY void*
#define VALUE void*
#define NODE void*
#define BTREE void*
BTREE createBTree(int treeID,KEY key,VALUE value);
int getID(BTREE tree);
bool releaseBTree(BTREE tree);
NODE addNode(BTREE tree,KEY key,VALUE value);
NODE findNode(BTREE tree,KEY key);
bool deleteNode(BTREE tree,KEY key);
NODE Min(BTREE tree);
NODE Max(BTREE tree);
NODE NextBigger(BTREE tree,NODE node);
NODE NextSmaller(BTREE tree,NODE node);
bool changeValue(BTREE tree,NODE node,VALUE value);
VALUE getValue(BTREE tree,NODE node);
KEY getKey(BTREE tree,NODE node);
extern int compareKey(int treeID,KEY compared,KEY base);//callback method
extern bool releaseKey(int treeID,KEY key); //callback method
extern bool releaseValue(int treeID,VALUE value); //callback method
//btree_i.h
#include "BTREE.h"
#include <windows.h>
typedef struct _node
{
_node* parent;
_node* left;
_node* right;
KEY key;
VALUE value;
} Node;
typedef struct _btree
{
int ID;
Node* rootNode;
}BTree;
typedef struct
{
Node * parent;
Node * left;
Node * right;
} FoundLocation;
FoundLocation _findLocation(BTree * tree,KEY key);
NODE _newNode(BTree* btree,KEY key,VALUE value);
//btee_i.cpp
#include "stdafx.h"
#include "BTREE.h"
#include "BTREE_i.h"
#include <memory.h>
#include <stdio.h>
Node * _newNode(KEY key,VALUE value)
{
Node* nd = new Node();
memset(nd,0,sizeof(Node));
nd->key = key;
nd->value = value;
return nd;
}
FoundLocation _findLocation(BTree* tree,KEY key)
{
FoundLocation loc;
Node * currNode = tree->rootNode;
Node * leftNode = NULL;
Node * rightNode = NULL;
bool bFound = false;
int compareResult = 0;
int compareResult1 = 0;
while(!bFound)
{
compareResult = compareKey(tree->ID,key,currNode->key);
if( compareResult == 0)
{
loc.parent = currNode;
loc.left = NULL;
loc.right = NULL;
bFound = true;
}
else if ( compareResult < 0)
{
if(currNode->left)
{
compareResult1 = compareKey(tree->ID,key,currNode->left->key);
if(compareResult1 == 0)
{
loc.parent = currNode->left;
loc.left = NULL;
loc.right = NULL;
bFound = true;
}
else if (compareResult1 < 0)
{
currNode = currNode->left;
//continue to find
}
else
{
loc.parent = currNode;
loc.left = currNode->left;
loc.right = NULL;
bFound = true;
}
}
else
{
loc.parent = currNode;
loc.left = (Node *)1;//means should add it in the left leaf of parent
loc.right = NULL;
bFound = true;
}
}
else
{
if(currNode->right)
{
compareResult1 = compareKey(tree->ID,key,currNode->right->key);
if(compareResult1 == 0)
{
loc.parent = currNode->right;
loc.left = NULL;
loc.right = NULL;
bFound = true;
}
else if (compareResult1 < 0)
{
loc.parent = currNode;
loc.left = NULL;
loc.right = currNode->right;
bFound = true;
}
else
{
currNode = currNode->right;
//continue to find
}
}
else
{
loc.parent = currNode;
loc.left = NULL;
loc.right = (Node*)1;means should add it in the right leaf of parent
bFound = true;
}
}
}
return loc;
}
BTREE createBTree(int ID,KEY key,VALUE value)
{
Node * rootNode = _newNode(key,value);
BTree* btree = new BTree();
btree->rootNode = rootNode;
btree->ID = ID;
return btree;
}
int getID(BTREE tree)
{
BTree* bt = (BTree*)tree;
return bt->ID;
}
bool releaseBTree(BTREE tree)
{
Node* currNode;
Node* nextNode;
BTree* btree = (BTree*)tree;
//first we delete left leaf of root node
currNode = (Node*)Min(tree);
while(currNode->parent != NULL && currNode!=NULL)
{
nextNode = (Node*)NextBigger(tree,currNode);
releaseKey(getID(tree),currNode->key);
if(currNode->value)
releaseValue(getID(tree),currNode->value);
if(currNode->right)
{
currNode->right->parent = currNode->parent;
currNode->parent->left = currNode->right;
}
else
{
currNode->parent->left = 0;
}
delete currNode;
currNode = nextNode;
}
//secondly,we delete right leaf of root node
currNode = (Node*)Max(tree);
while(currNode->parent != NULL && currNode!=NULL)
{
nextNode = (Node*)NextSmaller(tree,currNode);
releaseKey(getID(tree),currNode->key);
if(currNode->value)
releaseValue(getID(tree),currNode->value);
if(currNode->left)
{
currNode->left->parent = currNode->parent;
currNode->parent->right = currNode->left;
}
else
{
currNode->parent->right = 0;
}
delete currNode;
currNode = nextNode;
}
//the key and value of rootnode should be deleted by user.
delete btree->rootNode;
delete btree;
return true;
//
}
NODE addNode(BTREE tree,KEY key,VALUE value)
{
BTree* bt = (BTree*)tree;
FoundLocation loc = _findLocation(bt,key);
Node * node = NULL;
if(loc.left == 0 )
{
if(loc.right == 0)
{
printf("have added it before");
}
else if (loc.right == (Node *)1)
{
node = _newNode(key,value);
loc.parent->right = node;
node->parent = loc.parent;
}
else
{
node = _newNode(key,value);
node->parent = loc.parent ;
node->right = loc.right;
loc.parent->right = node;
loc.right->parent = node;
}
}
else if (loc.left == (Node *)1)
{
node = _newNode(key,value);
loc.parent->left = node;
node->parent = loc.parent;
}
else
{
node = _newNode(key,value);
node->parent = loc.parent ;
node->left = loc.left;
loc.parent->left = node;
loc.left->parent = node;
}
return node;
}
bool deleteNode(BTREE tree,KEY key)
{
BTree* bt = (BTree*)tree;
FoundLocation loc = _findLocation(bt,key);
if(!(loc.parent != NULL && loc.left == 0 && loc.right ==0 ))
return false;//cann't find it actually
Node * currNode = loc.parent;
Node * parentNode = currNode->parent;
Node * leftNode = currNode->left;
Node * rightNode = currNode->right;
Node * tmpNode;
if(parentNode == NULL)//this is for rootnode
{
if(currNode->left == NULL)
{
if(currNode->right != NULL)
{
currNode->right->parent = NULL;
bt->rootNode = currNode->right;
}else
{
bt->rootNode = NULL;
}
}
else
{
if(currNode->right == NULL)
{
currNode->left->parent = NULL;
bt->rootNode = currNode->left;
}
else
{
currNode->right->parent = NULL;
bt->rootNode = currNode->right;
tmpNode = currNode->right;
while(tmpNode->left != NULL)
{
tmpNode = tmpNode->left;
}
currNode->left->parent = tmpNode;
tmpNode->left = currNode->left;
}
}
delete currNode;
return true;
}
bool isLeftLeaf = parentNode->left == currNode;
if(isLeftLeaf)
{
if(currNode->right == NULL)
{
if(currNode->left !=NULL)
{
currNode->left->parent = parentNode;
parentNode->left = currNode->left;
}
else
{
parentNode->left = NULL;
}
}
else
{
if(currNode->left ==NULL)
{
currNode->right->parent = parentNode;
parentNode->left = currNode->right;
}
else
{
currNode->left->parent = parentNode;
parentNode->left = currNode->left;
tmpNode = currNode->left;
while(tmpNode->right != NULL)
{
tmpNode = tmpNode->right;
}
currNode->right->parent = tmpNode;
tmpNode->right = currNode->right;
}
}
}
else //rightleaf
{
if(currNode->left == NULL)
{
if(currNode->right !=NULL)
{
currNode->right->parent = parentNode;
parentNode->right = currNode->right;
}
else
{
parentNode->right = NULL;
}
}
else
{
if(currNode->right ==NULL)
{
currNode->left->parent = parentNode;
parentNode->right = currNode->left;
}
else
{
currNode->right->parent = parentNode;
parentNode->right = currNode->right;
tmpNode = currNode->right;
while(tmpNode->left != NULL)
{
tmpNode = tmpNode->left;
}
currNode->left->parent = tmpNode;
tmpNode->left = currNode->left;
}
}
}
delete currNode;
return true;
}
NODE findNode(BTREE tree,KEY key)
{
FoundLocation loc = _findLocation((BTree*)tree,key);
if(loc.parent != NULL && loc.left == 0 && loc.right ==0 )//find it
return (NODE )(loc.parent);
else
return NULL;
}
bool changeValue(BTREE tree,NODE node,VALUE value)
{
Node * nd = (Node*) node;
if(nd)
{
if(nd->value)
releaseValue(getID(tree),nd->value);
nd->value = value;
return true;
}
else
return false;
}
VALUE getValue(BTREE tree,NODE node)
{
Node * nd = (Node*) node;
return (VALUE)nd->value;
}
KEY getKey(BTREE tree,NODE node)
{
Node * nd = (Node*) node;
return (VALUE)nd->key;
}
NODE Min(BTREE tree)
{
BTree* bt = (BTree*)tree;
Node * currNode = bt->rootNode;
while(currNode->left != NULL)
{
currNode = currNode->left;
};
return (NODE)currNode;
}
NODE Max(BTREE tree)
{
BTree* bt = (BTree*)tree;
Node * currNode = bt->rootNode;
while(currNode->right != NULL)
{
currNode = currNode->right;
}
return (NODE)currNode;
}
NODE NextBigger(BTREE tree,NODE node)
{
BTree* bt = (BTree*)tree;
Node * nd = (Node*)node;
if(nd->right != 0)
{
Node * currNode = nd->right;
while(currNode->left != NULL)
{
currNode = currNode->left;
}
return currNode;
}
else
{
Node * currNode = nd;
Node * parentNode = nd->parent;
while(parentNode != NULL && parentNode->parent !=NULL && parentNode->right == currNode )
{
parentNode = parentNode->parent;
currNode = currNode->parent;
}
if(parentNode == NULL)
{
return 0;//this is only one
}
if(parentNode->parent == NULL)
{
if( currNode == parentNode->left)
return parentNode;
else
return 0;//not found actually,the current one is the max.
}
if(parentNode->right == NULL)
return parentNode;
currNode = parentNode;
while(currNode->left != NULL)
{
currNode = currNode->left;
}
return currNode;
}
}
NODE NextSmaller(BTREE tree,NODE node)
{
BTree* bt = (BTree*)tree;
Node * nd = (Node*)node;
if(nd->left != 0)
{
Node * currNode = nd->left;
while(currNode->right != NULL)
{
currNode = currNode->right;
}
return currNode;
}
else
{
Node * currNode = nd;
Node * parentNode = nd->parent;
while(parentNode != NULL && parentNode->parent !=NULL && parentNode->left == currNode )
{
parentNode = parentNode->parent;
currNode = currNode->parent;
}
if(parentNode == NULL)
{
return 0;//this is only one
}
if(parentNode->parent == NULL)
{
if( currNode == parentNode->right)
return parentNode;
else
return 0;//not found actually,the current one is the max.
}
if(parentNode->left == NULL)
return parentNode;
currNode = parentNode;
while(currNode->right != NULL)
{
currNode = currNode->right;
}
return currNode;
}
}