奉献我的一个二叉树的实现

 利用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;
 }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值