数据结构-树的基本操作
#include <stdio.h> #include <malloc.h> #include "GTree.h" #include "LinkList.h" typedef struct _tag_GTreeNode GTreeNode; /* 树的节点 */ struct _tag_GTreeNode { GTreeData* data; /* 节点自身数据 */ GTreeNode* parent; /* 父亲节点 */ LinkList* child; /* 孩子链表 */ }; typedef struct _tag_TLNode TLNode; /* 链表节点结构体,将树节点串成链表 */ struct _tag_TLNode { LinkListNode header; GTreeNode* node; }; static void recursive_display(GTreeNode* node, GTree_Printf* pFunc, int format, int gap, char div)/* 递归打印函数 定义为static外界看不到 format--缩进单位个数 gap--缩进单位 div--缩进形式 pFunc--打印函数*/ { int i = 0; if( (node != NULL) && (pFunc != NULL) ) { for(i=0; i<format; i++) { printf("%c", div); } pFunc(node->data); /* 打印数据 */ printf("\n"); for(i=0; i<LinkList_Length(node->child); i++) { TLNode* trNode = (TLNode*)LinkList_Get(node->child, i); recursive_display(trNode->node, pFunc, format + gap, gap, div); } } } static void recursive_delete(LinkList* list, GTreeNode* node) /* 递归删除函数 要删除该节点的所有函数 */ { if( (list != NULL) && (node != NULL) ) { GTreeNode* parent = node->parent; /* 要删除的节点的父亲节点 */ int index = -1; int i = 0; for(i=0; i<LinkList_Length(list); i++) /* 从树的组织链表中删除该节点 */ { TLNode* trNode = (TLNode*)LinkList_Get(list, i); if( trNode->node == node ) { LinkList_Delete(list, i); free(trNode); index = i; /* 标记位:表面从组织链表中删除成功 */ break; } } if( index >= 0 ) { if( parent != NULL ) /* 从父亲节点的孩子链表中删除该节点 */ { for(i=0; i<LinkList_Length(parent->child); i++) { TLNode* trNode = (TLNode*)LinkList_Get(parent->child, i); if( trNode->node == node ) { LinkList_Delete(parent->child, i); free(trNode); break; } } } while( LinkList_Length(node->child) > 0 ) /* 删除要删除的节点的孩子节点 */ { TLNode* trNode = (TLNode*)LinkList_Get(node->child, 0); /* 从孩子链表中一个一个取出来 递归删除所有孩子节点 */ recursive_delete(list, trNode->node); } LinkList_Destroy(node->child); /* 销毁要删除节点的孩子链表 */ free(node); /* 将insert申请的内存释放 */ } } } static int recursive_height(GTreeNode* node) /* 递归算出树的高度 计算一个树的高度首先要算出子树的高度后+1 */ { int ret = 0; if( node != NULL ) { int subHeight = 0; int i = 0; for(i=0; i<LinkList_Length(node->child); i++) { TLNode* trNode = (TLNode*)LinkList_Get(node->child, i); /* 从链表中取出子树的根节点 */ subHeight = recursive_height(trNode->node); if( ret < subHeight ) { ret = subHeight; } } ret = ret + 1; /* 加上根节点 故要+1 */ } return ret; } static int recursive_degree(GTreeNode* node) /* 定义静态函数 外部无法看到 递归算出 */ { int ret = -1; if( node != NULL ) { int subDegree = 0; int i = 0; ret = LinkList_Length(node->child); for(i=0; i<LinkList_Length(node->child); i++) { TLNode* trNode = (TLNode*)LinkList_Get(node->child, i); subDegree = recursive_degree(trNode->node); if( ret < subDegree ) /* 取最大值 */ { ret = subDegree; } } } return ret; } GTree* GTree_Create() { return LinkList_Create(); } void GTree_Destroy(GTree* tree) /* 此处数据封装 用户表面看起来只是一个tree(实际为一个单链表) */ { GTree_Clear(tree); LinkList_Destroy(tree); } void GTree_Clear(GTree* tree) { GTree_Delete(tree, 0); /* 删除根节点就相当于删除整个树 */ } int GTree_Insert(GTree* tree, GTreeData* data, int pPos) /* pPos---代表要插入的数据的父亲在表中的位置 */ { LinkList* list = (LinkList*)tree; int ret = (list != NULL) && (data != NULL) && (pPos < LinkList_Length(list)); /* 合法性检测 pPos至少小于树节点(链表)长度 */ if( ret ) { TLNode* trNode = (TLNode*)malloc(sizeof(TLNode)); /* (树)组织节点 */ TLNode* cldNode = (TLNode*)malloc(sizeof(TLNode)); /* child节点 *---插入某个节点时,要将其插入两个链表,一个是组织链表,一个是父亲节点的子节点链表 */ TLNode* pNode = (TLNode*)LinkList_Get(list, pPos); /* 从树中(链表)中取出pPos位置的节点 强制转换为TLnode---里面有指向树节点的指针 */ GTreeNode* cNode = (GTreeNode*)malloc(sizeof(GTreeNode)); /* 申请一个树节点 */ ret = (trNode != NULL) && (cldNode != NULL) && (cNode != NULL); if( ret ) { cNode->data = data; /* 对新创建的通用节点赋值 */ cNode->parent = NULL; /* 暂时指定该节点没有双亲 */ cNode->child = LinkList_Create(); trNode->node = cNode; cldNode->node = cNode; LinkList_Insert(list, (LinkListNode*)trNode, LinkList_Length(list)); /* 插入到组织链表中 */ if( pNode != NULL ) /* 根节点没有双亲 故此处要判断 */ { cNode->parent = pNode->node; /* 将申请的节点赋给父亲节点 */ LinkList_Insert(pNode->node->child, (LinkListNode*)cldNode, LinkList_Length(pNode->node->child)); /* 插入到父亲节点的孩子链表中 */ } } else { free(trNode); free(cldNode); free(cNode); } } return ret; } GTreeData* GTree_Delete(GTree* tree, int pos) { TLNode* trNode = (TLNode*)LinkList_Get(tree, pos); GTreeData* ret = NULL; /* 要删除的节点里保存的数据 */ if( trNode != NULL ) { ret = trNode->node->data; recursive_delete(tree, trNode->node); /* 递归删除,要删除所有孩子 */ } return ret; } GTreeData* GTree_Get(GTree* tree, int pos) /* 从组织链表中pos节点的数据返回 */ { TLNode* trNode = (TLNode*)LinkList_Get(tree, pos); GTreeData* ret = NULL; if( trNode != NULL ) { ret = trNode->node->data; } return ret; } GTreeData* GTree_Root(GTree* tree) { return GTree_Get(tree, 0); } int GTree_Height(GTree* tree) { TLNode* trNode = (TLNode*)LinkList_Get(tree, 0); int ret = 0; if( trNode != NULL ) { ret = recursive_height(trNode->node); } return ret; } int GTree_Count(GTree* tree) { return LinkList_Length(tree); } int GTree_Degree(GTree* tree) { TLNode* trNode = (TLNode*)LinkList_Get(tree, 0); int ret = -1; if( trNode != NULL ) { ret = recursive_degree(trNode->node); } return ret; } void GTree_Display(GTree* tree, GTree_Printf* pFunc, int gap, char div) { TLNode* trNode = (TLNode*)LinkList_Get(tree, 0); if( (trNode != NULL) && (pFunc != NULL) ) { recursive_display(trNode->node, pFunc, 0, gap, div); } }