From bb069ae9e97daf40e9c90301d56016745b5a594c Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 19 Jul 2014 07:44:42 +0000 Subject: [PATCH] Initial import git-svn-id: http://moon:8086/svn/software/trunk/libsrc/bintree@1 b431acfa-c32f-4a4a-93f1-934dc6c82436 --- bintree.c | 367 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ bintree.h | 42 +++++++ 2 files changed, 409 insertions(+) create mode 100755 bintree.c create mode 100755 bintree.h diff --git a/bintree.c b/bintree.c new file mode 100755 index 0000000..4908515 --- /dev/null +++ b/bintree.c @@ -0,0 +1,367 @@ +// ------------------------------------------------------------ +// bintree.c +// Implementation of a binary tree +// +// 27.02.2005, J.Ahrensfeld +// ------------------------------------------------------------ +#include +#include +#include +#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->valuevalue>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; + +} + +// ------------------------------------------------------------ diff --git a/bintree.h b/bintree.h new file mode 100755 index 0000000..6e1c40a --- /dev/null +++ b/bintree.h @@ -0,0 +1,42 @@ +// ------------------------------------------------------------ +// bintree.h +// Implementation of a binary tree +// +// 27.02.2005, J.Ahrensfeld +// ------------------------------------------------------------ +#ifndef BINTREE_H +#define BINTREE_H + +// ------------------------------------------------------------ +typedef struct _node_t +{ + double value; + void *pData; + + struct _node_t *pParent; + struct _node_t *pLeft; + struct _node_t *pRight; + +} node_t; + +// ------------------------------------------------------------ +node_t* node_init(node_t *pObj, double value, void *pData, int size); +node_t* node_insert(node_t *pObj, double value, void *pData, int size); +node_t* node_lookup(node_t *pObj, double value); +node_t* node_remove(node_t *pObj); +void bintree_print(node_t *pObj); +int bintree_size(node_t *pObj); +int bintree_maxdepth(node_t *pObj); +double bintree_minvalue(node_t *pObj); +double bintree_maxvalue(node_t *pObj); +node_t *bintree_GetLeafMax(node_t *pObj); +node_t *bintree_GetLeafMin(node_t *pObj); +int bintree_isBST(node_t *pObj); +int bintree_isBSTUtil(node_t *pObj, double min, double max); +node_t *bintree_GetNodeMax(node_t *pObj); +node_t *bintree_GetNodeMin(node_t *pObj); +int bintree_destroy(node_t *pObj); + + +// ------------------------------------------------------------ +#endif // BINTREE_H