ZE-Standard-Libraries/tree/tree.h

491 lines
12 KiB
C
Raw Normal View History

2018-06-12 05:51:42 +00:00
#pragma once
2018-06-12 09:03:31 +00:00
#include "../list/list_expand.h"
typedef struct tree_node
{
unsigned long long id;
List *home;
struct tree_node *father;
Node *room;
unsigned long long child_num;
char *type;
void *value;
int if_malloc;
}TNode;
typedef struct tree
{
unsigned long long id;
TNode *root;
}Tree;
2018-06-12 09:57:23 +00:00
List *tree_list = NULL;
List *tnode_list = NULL;
int if_safeModeForTree = 0;
int safeModeForTree(int ifon);
int releaseAllForTree(void);
2018-06-12 09:03:31 +00:00
TNode *initTNode(void);
Tree *initTree(void);
int *initMallocValueForTNode(TNode *p_tnode, char *type, void *value);
int addChildInLeft(TNode *f_tnode, TNode *c_tnode);
int addChildInRight(TNode *f_tnode, TNode *c_tnode);
TNode *getBrotherInLeft(TNode *p_tnode);
TNode *getBrotherInRight(TNode *p_node);
int removeChildInLeft(TNode *p_tnode);
int removeChildInRight(TNode *p_tnode);
TNode *getChildById(TNode *p_tnode, unsigned long long id);
TNode *getChildByValue(TNode *p_tnode, char *type, void *value);
TNode *getChildByIndex(TNode *p_tnode, unsigned long long index);
unsigned long long getIndexByChild(TNode *f_tnode, TNode *c_tnode);
int removeChildById(TNode *p_tnode, unsigned long long id);
int removeChildByIndex(TNode *p_tnode, unsigned long long index);
int removeChildByValue(TNode *p_tnode, char *type, void *value);
int TreeThroughDown(Tree *p_tree, int(*func)(TNode *, unsigned long long height));
int TreeThroughUp(Tree *p_tree, int(*func)(TNode *, unsigned long long height));
2018-06-12 09:57:23 +00:00
int TreeTravel(Tree *p_tree, int(*func)(TNode *, unsigned long long height));
int releaseTree(Tree *p_tree);
int releaseOnlyTree(Tree *p_tree);
int releaseTNode(TNode *p_tnode);
int releaseOnlyTNode(Tree *p_tree);
int safeModeForTree(int ifon) {
if (ifon == 1) {
if (tnode_list == NULL && tree_list == NULL) {
tnode_list = (List *)malloc(sizeof(List));
tree_list = (List *)malloc(sizeof(List));
tree_list->head = NULL;
tree_list->length = 0;
tree_list->tail = NULL;
tnode_list->head = NULL;
tnode_list->length = 0;
tnode_list->tail = NULL;
if_safeModeForTree = 1;
}
else {
return -1;
}
}
return ifon;
}
2018-06-12 09:03:31 +00:00
TNode *initTNode(void) {
TNode *p_tnode = (TNode *)malloc(sizeof(TNode));
p_tnode->id = getId();
p_tnode->child_num = 0;
p_tnode->father = NULL;
p_tnode->if_malloc = 0;
p_tnode->value = NULL;
p_tnode->type = NULL;
p_tnode->home = initList();
p_tnode->room = NULL;
2018-06-12 09:57:23 +00:00
if (if_safeModeForTree) {
if (if_safeModeForNode) {
if_safeModeForNode = 0;
Node *s_node = initNode();
initMallocValueForTNode(s_node, "pointer", (void *)p_tnode);
insertInTail(tnode_list, s_node);
if_safeModeForNode = 1;
}
else
{
Node *s_node = initNode();
initMallocValueForTNode(s_node, "pointer", (void *)p_tnode);
insertInTail(tnode_list, s_node);
}
}
2018-06-12 09:03:31 +00:00
return p_tnode;
}
Tree *initTree(void) {
Tree *p_tree = (Tree *)malloc(sizeof(Tree));
p_tree->id = getId();
p_tree->root = NULL;
2018-06-12 09:57:23 +00:00
if (if_safeModeForTree) {
if (if_safeModeForNode) {
if_safeModeForNode = 0;
Node *s_node = initNode();
initMallocValueForTNode(s_node, "pointer", (void *)p_tree);
if_safeModeForNode = 1;
insertInTail(tree_list, s_node);
}
else
{
Node *s_node = initNode();
initMallocValueForTNode(s_node, "pointer", (void *)p_tree);
insertInTail(tree_list, s_node);
}
}
2018-06-12 09:03:31 +00:00
return p_tree;
}
int *initMallocValueForTNode(TNode *p_tnode, char *type, void *value) {
p_tnode->type = type;
p_tnode->value = value;
p_tnode->if_malloc = 1;
return 0;
}
int addChildInLeft(TNode *f_tnode, TNode *c_tnode) {
Node *p_node = initNode();
initMalllocValueForNode(p_node, "pointer", c_tnode);
insertInHead(f_tnode->home, p_node);
c_tnode->father = f_tnode;
f_tnode->child_num++;
return 0;
}
int addChildInRight(TNode *f_tnode, TNode *c_tnode) {
Node *p_node = initNode();
initMalllocValueForNode(p_node, "pointer", c_tnode);
insertInTail(f_tnode->home, p_node);
c_tnode->father = f_tnode;
f_tnode->child_num++;
return 0;
}
TNode *getBrotherInLeft(TNode *p_tnode) {
List *p_home = p_tnode->father->home;
Node *p_node =p_home->head;
int index = getIndexByNode(p_home, p_node);
if (index > 0) return findByIndexForNode(p_home, index -1);
return NULL;
}
TNode *getBrotherInRight(TNode *p_tnode) {
List *p_home = p_tnode->father->home;
Node *p_node = p_home->head;
int index = getIndexByNode(p_home, p_node);
if (index < p_home->length-1) return findByIndexForNode(p_home, index + 1);
return NULL;
}
int removeChildInLeft(TNode *p_tnode) {
TNode *c_tnode = p_tnode->home->head;
c_tnode->father = NULL;
releaseOnlyNode(c_tnode->room);
c_tnode->room = NULL;
p_tnode->child_num--;
popFromHead(p_tnode->home);
}
int removeChildInRight(TNode *p_tnode) {
TNode *c_tnode = p_tnode->home->tail;
c_tnode->father = NULL;
releaseOnlyNode(c_tnode->room);
c_tnode->room = NULL;
p_tnode->child_num--;
popFromTail(p_tnode->home);
}
unsigned long long target_id = 0;
TNode *target_value_id = NULL;
TNode*_dogetChildById(char *type, void *value);
TNode *getChildById(TNode *p_tnode, unsigned long long id) {
List *p_home = p_tnode->home;
target_id = 0;
target_value_id = NULL;
listThrough(p_home, _dogetChildById);
if (target_value_id != NULL) {
return target_value_id;
}
return NULL;
}
TNode*_dogetChildById(char *type, void *value) {
if (!strcmp(type, "pointer")) {
TNode *p_tode = (TNode *)value;
if (p_tode->id == target_id) {
target_value_id = p_tode;
return -1;
}
}
return 0;
}
char *target_type = NULL;
void *target_value = NULL;
TNode *target_value_value = NULL;
TNode*_dogetChildByValue(char *type, void *value);
TNode *getChildByValue(TNode *p_tnode, char *type, void *value) {
List *p_home = p_tnode->home;
target_value = value;
target_type = type;
target_value_value = NULL;
listThrough(p_home, _dogetChildByValue);
if (target_value_value != NULL) {
return target_value_value;
}
return NULL;
}
TNode*_dogetChildByValue(char *type, void *value) {
if (!strcmp(type, target_type)) {
TNode *p_tode = (TNode *)value;
if (!strcmp(target_value, "int")) {
if (*(int *)p_tode->value == *(int *)target_value)
{
target_value_value = p_tode;
return -1;
}
}
else if (!strcmp(target_value, "double"))
{
if (*(double *)p_tode->value == *(double *)target_value)
{
target_value_value = p_tode;
return -1;
}
}
else if (!strcmp(target_value, "string"))
{
if (!strcmp((char *)p_tode->value,(char *)target_value))
{
target_value_value = p_tode;
return -1;
}
}
else if (!strcmp(target_value, "pointer"))
{
if (p_tode->value == target_value)
{
target_value_value = p_tode;
return -1;
}
}
}
return 0;
}
int removeChildById(TNode *p_tnode, unsigned long long id) {
TNode *t_tnode = getChildById(p_tnode, id);
if (t_tnode != NULL) {
TNode *p_fnode = t_tnode->father;
p_fnode->child_num--;
removeById(p_fnode->home, t_tnode->room->id);
releaseOnlyNode(t_tnode->room);
t_tnode->room = NULL;
return 0;
}
return -1;
}
int removeChildByValue(TNode *p_tnode, char *type, void *value) {
TNode *t_tnode = getChildByValue(p_tnode, type, value);
if (t_tnode != NULL) {
TNode *p_fnode = t_tnode->father;
p_fnode->child_num--;
removeById(p_fnode->home, t_tnode->room->id);
releaseOnlyNode(t_tnode->room);
t_tnode->room = NULL;
return 0;
}
return -1;
}
TNode *getChildByIndex(TNode *p_tnode, unsigned long long index) {
List *p_home = p_tnode->home;
Node *p_node = p_home->head;
int m_index = 0;
if (index < p_tnode->child_num-1)
{
while (p_node != NULL) {
m_index++;
p_node = p_node->next;
}
return (TNode *)p_node->value;
}
return NULL;
}
unsigned long long getIndexByChild(TNode *f_tnode, TNode *c_tnode) {
List *p_home = f_tnode->home;
Node *p_node = p_home->head;
int m_index = 0;
while (p_node != NULL) {
TNode *p_tnode = (TNode *)p_node->value;
if (p_tnode->id == c_tnode->id) {
return m_index;
}
m_index++;
p_node = p_node->next;
}
return NULL;
}
int removeChildByIndex(TNode *p_tnode, unsigned long long index){
TNode *t_tnode = getChildByIndex(p_tnode, index);
if (t_tnode != NULL) {
TNode *p_fnode = t_tnode->father;
p_fnode->child_num--;
removeById(p_fnode->home, t_tnode->room->id);
releaseOnlyNode(t_tnode->room);
t_tnode->room = NULL;
return 0;
}
return -1;
}
int TreeThroughUp(Tree *p_tree, int(*func)(TNode *, unsigned long long height)) {
TNode *p_tnode = p_tree->root;
if (p_tnode != NULL) {
func(p_tnode, 0);
if (p_tnode->child_num > 0) {
for (int i = 0; i < p_tnode->child_num; i++) {
if (_doTreeThroughDown(getChildByIndex(p_tnode, i), 1, func) == -1) {
break;
}
}
}
}
return 0;
}
int _doTreeThroughUp(TNode *p_tnode, int height, int(*func)(TNode *, unsigned long long height)) {
if (p_tnode->child_num > 0) {
for (int i = 0; i < p_tnode->child_num; i++) {
if (_doTreeThroughDown(getChildByIndex(p_tnode, i), height + 1, func)) return -1;
}
}
int func_back = func(p_tnode, height);
if (func_back == -1)return -1;
return 0;
}
int TreeThroughDown(Tree *p_tree, int(*func)(TNode *, unsigned long long height)) {
TNode *p_tnode = p_tree->root;
if (p_tree->root != NULL) {
if (p_tree->root->child_num > 0) {
func(p_tnode, 0);
for (int i = 0; i < p_tnode->child_num; i++) {
if (_doTreeThroughDown(getChildByIndex(p_tnode, i), 1, func) == -1) {
break;
}
}
}
}
return 0;
}
int _doTreeThroughDown(TNode *p_tnode, int height, int(*func)(TNode *, unsigned long long height)) {
int func_back = func(p_tnode, height);
if (p_tnode->child_num > 0) {
for (int i = 0; i < p_tnode->child_num; i++) {
if (_doTreeThroughDown(getChildByIndex(p_tnode, i), height + 1, func)) return -1;
}
}
if (func_back == -1)return -1;
return 0;
}
2018-06-12 09:57:23 +00:00
int TreeTravel(Tree *p_tree, int(*func)(TNode *, unsigned long long height)) {
TNode *p_tnode = p_tree->root;
unsigned long long height = 0;
if (p_tnode != NULL) {
int func_back = func(p_tnode, height);
while (func_back > -2) {
if (func_back > -1) {
p_tnode = getChildByIndex(func_back,func_back);
func(p_tnode, height + 1);
}
else
{
p_tnode = p_tnode->father;
func(p_tnode, height - 1);
}
}
}
return 0;
}
int releaseTNode(TNode *p_tnode) {
if(p_tnode->child_num == 0){
releaseList(p_tnode->home);
if (p_tnode->father != NULL) {
removeChildById(p_tnode->father, p_tnode->id);
}
if (strcmp(p_tnode->type, "pointer")) {
if (!strcmp(p_tnode->type, "list")) {
releaseList((List *)p_tnode->value);
}
else {
free(p_tnode->value);
}
}
p_tnode->value = NULL;
p_tnode->type = NULL;
p_tnode->id = 0;
p_tnode->if_malloc = 0;
free(p_tnode);
}
return 0;
}
int _doreleaseTree(TNode *p_tnode, int height);
int releaseTree(Tree *p_tree) {
TreeThroughUp(p_tree, _doreleaseTree);
p_tree->root = NULL;
p_tree->id = 0;
free(p_tree);
}
int _doreleaseTree(TNode *p_tnode, int height) {
releaseTNode(p_tnode);
return 0;
}
int releaseOnlyTree(Tree *p_tree) {
p_tree->id = 0;
p_tree->root = NULL;
free(p_tree);
return 0;
}
int releaseOnlyTNode(TNode *p_tnode) {
releaseList(p_tnode->home);
if (strcmp(p_tnode->type, "pointer")) {
if (!strcmp(p_tnode->type, "list")) {
releaseList((List *)p_tnode->value);
}
else {
free(p_tnode->value);
}
}
p_tnode->value = NULL;
p_tnode->type = NULL;
p_tnode->id = 0;
p_tnode->if_malloc = 0;
free(p_tnode);
return 0;
}
int releaseAllForTree(void) {
if (if_safeModeForTree) {
if_safeModeForTree = 0;
Node *p_node = tnode_list->head;
while (p_node != NULL) {
TNode *p_tnode = (TNode *)p_node->value;
releaseOnlyTNode(p_tnode);
}
Node *p_node = tree_list->head;
while (p_node != NULL) {
Tree *p_tree = (Tree *)p_node->value;
releaseOnlyTree(p_tree);
}
releaseList(tnode_list);
releaseList(tree_list);
}
return 0;
}