#include"tree.h" static SID *target_sid = NULL; static TNode *target_value_sid = NULL; static int if_safeModeForTree = 0; int safeModeForTree(int ifon) { if (ifon == 1) { if (tnode_list == NULL && tree_list == NULL) { tnode_list = (List *)malloc(sizeof(List)); if(tnode_list == NULL){ showError(pushError(TREE_NODE, HIGH, initInfo("safeModeForTree()", "Error in get the memory of tnode_list."))); return -1; } tree_list = (List *)malloc(sizeof(List)); if(tree_list == NULL){ showError(pushError(TREE_NODE, HIGH, initInfo("safeModeForTree()", "Error in get the memory of tree_list."))); return -1; } 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; } TNode *initTNode(void) { Node *s_node; TNode *p_tnode = (TNode *)malloc(sizeof(TNode)); if(p_tnode == NULL){ showError(pushError(TREE_NODE, STANDARD, initInfo("initTNode()", "Error in get the memory of tnode."))); return NULL; } p_tnode->s_id = getS_id(TREE_NODE, 2); p_tnode->if_sid = 1; p_tnode->child_num = 0; p_tnode->father = NULL; p_tnode->if_malloc = 0; p_tnode->value = NULL; p_tnode->type = VOID; p_tnode->home = initList(); p_tnode->room = NULL; if (if_safeModeForTree) { if (if_safeModeForNode) { if_safeModeForNode = 0; s_node = initNode(); initMallocValueForNode(s_node, POINTER, (void *)p_tnode); insertInTail(tnode_list, s_node); if_safeModeForNode = 1; } else { s_node = initNode(); initMallocValueForNode(s_node, POINTER, (void *)p_tnode); insertInTail(tnode_list, s_node); } } return p_tnode; } Tree *initTree(void) { Node *s_node; Tree *p_tree = (Tree *)malloc(sizeof(Tree)); if(p_tree == NULL){ showError(pushError(TREE, STANDARD, initInfo("initTree()", "Error in get the memory of tree."))); return NULL; } p_tree->s_id = getS_id(TREE, 1); p_tree->if_sid = 1; p_tree->root = NULL; if (if_safeModeForTree) { if (if_safeModeForNode) { if_safeModeForNode = 0; s_node = initNode(); initMallocValueForNode(s_node, POINTER, (void *)p_tree); if_safeModeForNode = 1; insertInTail(tree_list, s_node); } else { s_node = initNode(); initMallocValueForNode(s_node, POINTER, (void *)p_tree); insertInTail(tree_list, s_node); } } return p_tree; } int *initMallocValueForTNode(TNode *p_tnode, unsigned int 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(); initMallocValueForNode(p_node, POINTER, c_tnode); insertInHead(f_tnode->home, p_node); c_tnode->father = f_tnode; c_tnode->room = p_node; f_tnode->child_num++; return 0; } int addChildInRight(TNode *f_tnode, TNode *c_tnode) { Node *p_node = initNode(); initMallocValueForNode(p_node, POINTER, c_tnode); insertInTail(f_tnode->home, p_node); c_tnode->father = f_tnode; c_tnode->room = p_node; f_tnode->child_num++; return 0; } TNode *getBrotherInLeft(TNode *p_tnode) { List *p_home = p_tnode->father->home; Node *p_node = p_tnode->room; unsigned long long index = getIndexByNode(p_home, p_node); if (index > 0) return (TNode *)(findByIndexForNode(p_home, index - 1)->value); return NULL; } TNode *getBrotherInRight(TNode *p_tnode) { List *p_home = p_tnode->father->home; Node *p_node = p_home->head; unsigned long long index = getIndexByNode(p_home, p_node); if (index < p_home->length - 1) return (TNode *)(findByIndexForNode(p_home, index + 1)->value); return NULL; } int removeChildInLeft(TNode *p_tnode) { TNode *c_tnode = (TNode *)p_tnode->home->head->value; c_tnode->father = NULL; releaseOnlyNode(c_tnode->room); c_tnode->room = NULL; p_tnode->child_num--; popFromHead(p_tnode->home); return 0; } int removeChildInRight(TNode *p_tnode) { TNode *c_tnode = (TNode *)p_tnode->home->tail->value; c_tnode->father = NULL; releaseOnlyNode(c_tnode->room); c_tnode->room = NULL; p_tnode->child_num--; popFromTail(p_tnode->home); return 0; } TNode *getChildById(TNode *p_tnode, const SID *s_id) { List *p_home = p_tnode->home; target_sid = NULL; target_value_sid = NULL; listThrough(p_home, _dogetChildById); if (target_value_sid != NULL) { return target_value_sid; } return NULL; } int _dogetChildById(unsigned int type, void *value) { if (type == POINTER) { TNode *p_tode = (TNode *)value; if (simFitS_id(p_tode->s_id, target_sid)) { target_value_sid = p_tode; return -1; } } return 0; } static int target_type = VOID; static void *target_value = NULL; static TNode *target_value_value = NULL; TNode *getChildByValue(TNode *p_tnode, unsigned int 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; } int _dogetChildByValue(unsigned int type, void *value) { if (type == target_type) { TNode *p_tode = (TNode *)value; if (target_type == INT) { if (*(int *)p_tode->value == *(int *)target_value) { target_value_value = p_tode; return -1; } } else if (target_type == DOUBLE) { if (*(double *)p_tode->value == *(double *)target_value) { target_value_value = p_tode; return -1; } } else if (target_type == STRING) { if (!strcmp((char *)p_tode->value, (char *)target_value)) { target_value_value = p_tode; return -1; } } else if (target_type == POINTER) { if (p_tode->value == target_value) { target_value_value = p_tode; return -1; } } } return 0; } int removeChildById(TNode *p_tnode, const SID *s_id) { TNode *t_tnode = getChildById(p_tnode, s_id); if (t_tnode != NULL) { TNode *p_fnode = t_tnode->father; p_fnode->child_num--; removeById(p_fnode->home, t_tnode->room->s_id); releaseOnlyNode(t_tnode->room); t_tnode->room = NULL; return 0; } return -1; } int removeChildByValue(TNode *p_tnode, unsigned int 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->s_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) { while (p_node != NULL && m_index < index) { 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->s_id == c_tnode->s_id) { return m_index; } m_index++; p_node = p_node->next; } return -1; } 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->s_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)) { int i; TNode *p_tnode = p_tree->root; if (p_tnode != NULL) { if (p_tnode->child_num > 0) { for (i = 0; i < p_tnode->child_num; i++) { if (_doTreeThroughUp(getChildByIndex(p_tnode, i), 1, func) == -1) { break; } } } func(p_tnode, 0); } return 0; } int _doTreeThroughUp(TNode *p_tnode, int height, int(*func)(TNode *, unsigned long long height)) { int i, func_back; if (p_tnode->child_num > 0) { for (i = 0; i < p_tnode->child_num; i++) { if (_doTreeThroughUp(getChildByIndex(p_tnode, i), height + 1, func)) return -1; } } 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)) { int i; TNode *p_tnode = p_tree->root; if (p_tree->root != NULL) { func(p_tnode, 0); if (p_tree->root->child_num > 0) { for (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 i; int func_back = func(p_tnode, height); if (p_tnode->child_num > 0) { for (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; } 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(p_tnode, 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->s_id); } if (p_tnode->type != POINTER) { if (p_tnode->type == LIST) { releaseList((List *)p_tnode->value); } else { free(p_tnode->value); } } p_tnode->value = NULL; p_tnode->type = VOID; freeS_id(p_tnode->s_id); p_tnode->if_malloc = 0; free(p_tnode); } return 0; } int releaseTree(Tree *p_tree) { TreeThroughUp(p_tree, _doreleaseTree); p_tree->root = NULL; freeS_id(p_tree->s_id); free(p_tree); return 0; } int _doreleaseTree(TNode *p_tnode, unsigned long long height) { releaseTNode(p_tnode); return 0; } int releaseOnlyTree(Tree *p_tree) { freeS_id(p_tree->s_id); p_tree->root = NULL; free(p_tree); return 0; } int releaseOnlyTNode(TNode *p_tnode) { releaseList(p_tnode->home); if (p_tnode->if_malloc) { if (p_tnode->type != STRING) { if (p_tnode->type == LIST) { releaseList((List *)p_tnode->value); } else { free(p_tnode->value); } } } p_tnode->value = NULL; p_tnode->type = VOID; freeS_id(p_tnode->s_id); p_tnode->if_malloc = 0; free(p_tnode); return 0; } int releaseAllForTree(void) { Node *p_node; Tree *p_tree; if (if_safeModeForTree) { if_safeModeForTree = 0; p_node = tnode_list->head; while (p_node != NULL) { TNode *p_tnode = (TNode *)p_node->value; releaseOnlyTNode(p_tnode); p_node = p_node->next; } p_node = tree_list->head; while (p_node != NULL) { p_tree = (Tree *)p_node->value; releaseOnlyTree(p_tree); p_node = p_node->next; } releaseList(tnode_list); releaseList(tree_list); } return 0; } int setRoot(Tree *p_tree, TNode *p_tnode) { p_tree->root = p_tnode; return 0; }