Files
jens bb069ae9e9 Initial import
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/bintree@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
2014-07-19 07:44:42 +00:00

368 lines
6.6 KiB
C
Executable File

// ------------------------------------------------------------
// bintree.c
// Implementation of a binary tree
//
// 27.02.2005, J.Ahrensfeld
// ------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bintree.h"
// ------------------------------------------------------------
node_t* GetParent(node_t *pObj)
{
if (!pObj)
return pObj;
if (!pObj->pParent)
return pObj;
return GetParent(pObj->pParent);
}
node_t* node_init(node_t *pObj, double value, void *pData, int size)
{
node_t *pNode;
pNode = (node_t*)malloc(sizeof(node_t));
pNode->pData = NULL;
if (size)
pNode->pData = malloc(size);
if (pData)
memcpy(pNode->pData, pData, size);
pNode->pParent = pObj;
pNode->pLeft = NULL;
pNode->pRight = NULL;
pNode->value = value;
return pNode;
}
node_t* node_insert(node_t *pObj, double value, void *pData, int size)
{
if(pObj == NULL)
{
return node_init(pObj, value, pData, size);
}
else
{
if(value <= pObj->value)
{
if (pObj->pLeft)
node_insert(pObj->pLeft, value, pData, size);
else
pObj->pLeft = node_init(pObj, value, pData, size);
}
else
{
if (pObj->pRight)
node_insert(pObj->pRight, value, pData, size);
else
pObj->pRight = node_init(pObj, value, pData, size);
}
}
return pObj;
}
node_t* node_lookup(node_t *pObj, double value)
{
return pObj;
}
node_t* node_remove(node_t *pNode)
{
node_t *pMin_leaf;
node_t *pParent;
void *pData;
double value;
if(pNode == NULL)
{
return pNode;
}
pParent = pNode->pParent;
if(!pNode->pLeft && !pNode->pRight)
{
if (pParent)
{
if(pParent->pLeft == pNode)
{
pParent->pLeft = NULL;
}
if(pParent->pRight == pNode)
{
pParent->pRight = NULL;
}
}
}
else
{
if(pNode->pLeft && !pNode->pRight)
{
pNode->pLeft->pParent = pParent;
if (pParent)
{
if(pParent->pLeft == pNode)
pParent->pLeft = pNode->pLeft;
if(pParent->pRight == pNode)
pParent->pRight = pNode->pLeft;
}
else
pParent = pNode->pLeft;
}
else
{
if(!pNode->pLeft && pNode->pRight)
{
pNode->pRight->pParent = pParent;
if (pParent)
{
if(pParent->pLeft == pNode)
pParent->pLeft = pNode->pRight;
if(pParent->pRight == pNode)
pParent->pRight = pNode->pRight;
}
else
pParent = pNode->pRight;
}
else
{
if(pNode->pLeft && pNode->pRight)
{
pMin_leaf = bintree_GetLeafMin(pNode);
value = pMin_leaf->value;
pData = pMin_leaf->pData;
pParent = node_remove(pMin_leaf);
pNode->pData = pData;
pNode->value = value;
}
}
}
}
if (pNode->pData)
free(pNode->pData);
free(pNode);
pNode = NULL;
return GetParent(pParent);
}
// ------------------------------------------------------------
void bintree_print(node_t *pObj)
{
if (pObj == NULL)
return;
bintree_print(pObj->pLeft);
printf("%g ", pObj->value);
bintree_print(pObj->pRight);
}
int bintree_size(node_t *pObj)
{
if (pObj==NULL)
{
return 0;
}
else
{
return(bintree_size(pObj->pLeft) + 1 + bintree_size(pObj->pRight));
}
}
int bintree_maxdepth(node_t *pObj)
{
int lDepth;
int rDepth;
if (pObj==NULL)
{
return(0);
}
else
{
// compute the depth of each subtree
lDepth = bintree_maxdepth(pObj->pLeft);
rDepth = bintree_maxdepth(pObj->pRight);
// use the larger one
if (lDepth > rDepth)
return(lDepth+1);
else
return(rDepth+1);
}
}
double bintree_minvalue(node_t *pObj)
{
node_t *current = pObj;
// loop down to find the leftmost leaf
while (current->pLeft != NULL)
{
current = current->pLeft;
}
return(current->value);
}
double bintree_maxvalue(node_t *pObj)
{
node_t *current = pObj;
// loop down to find the leftmost leaf
while (current->pRight != NULL)
{
current = current->pRight;
}
return(current->value);
}
// ------------------------------------------------------------
node_t *bintree_GetNodeMax(node_t *pObj)
{
node_t *pNode = pObj;
node_t *current = pNode;
if (!pNode)
return pNode;
// loop down to find the leftmost leaf
while (current->pRight != NULL)
{
current = current->pRight;
}
return current;
}
// ------------------------------------------------------------
node_t *bintree_GetNodeMin(node_t *pObj)
{
node_t *pNode = pObj;
node_t *current = pNode;
if (!pNode)
return pNode;
// loop down to find the leftmost leaf
while (current->pLeft != NULL)
{
current = current->pLeft;
}
return current;
}
// ------------------------------------------------------------
node_t *bintree_GetLeafMax(node_t *pObj)
{
node_t *current = pObj;
if(current->pRight != NULL)
current = bintree_GetLeafMax(current->pRight);
else
if(current->pLeft != NULL)
current = bintree_GetLeafMax(current->pLeft);
return current;
}
node_t *bintree_GetLeafMin(node_t *pObj)
{
node_t *current = pObj;
if(current->pLeft != NULL)
current = bintree_GetLeafMin(current->pLeft);
else
if(current->pRight != NULL)
current = bintree_GetLeafMin(current->pRight);
return current;
}
int bintree_isBST(node_t *pObj)
{
if (pObj==NULL)
return(1);
// false if the max of the left is > than us
// (bug -- an earlier version had min/max backwards here)
if (pObj->pLeft != NULL && bintree_maxvalue(pObj->pLeft) > pObj->value)
return(0);
// false if the min of the right is <= than us
if (pObj->pRight !=NULL && bintree_minvalue(pObj->pRight) <= pObj->value)
return(0);
// false if, recursively, the left or right is not a BST
if (!bintree_isBST(pObj->pLeft) || !bintree_isBST(pObj->pRight))
return(0);
// passing all that, it's a BST
return(1);
}
int bintree_isBSTUtil(node_t *pObj, double min, double max)
{
if (pObj==NULL)
return(1);
// false if this node violates the min/max constraint
if (pObj->value<min || pObj->value>max)
return(0);
// otherwise check the subtrees recursively,
// tightening the min or max constraint
return
(
bintree_isBSTUtil(pObj->pLeft, min, pObj->value) &&
bintree_isBSTUtil(pObj->pRight, pObj->value+1, max)
);
}
int bintree_destroy(node_t *pObj)
{
int size;
node_t *pRoot, *pMaxLeaf;
pRoot = pObj;
size = 1;
while(pRoot)
{
size = bintree_size(pRoot);
pMaxLeaf = bintree_GetLeafMax(pRoot);
pRoot = node_remove(pMaxLeaf);
};
if (size != 1)
return -1;
return 0;
}
// ------------------------------------------------------------