数据结构通用树
今天来看大家介绍树,树是一种非线性的数据结构,树是由n个结点组成的有限集合,如果n=0,称为空树;如果n>0,则:有一个特定的称之为根的结点,它只有直接后继,但没有直接前驱;除根以外的其他结点划分为m个互不相交的有限集合,每个集合又是一棵树,并且称之为根的子树。
如图
树的一些基本概念
l 树的结点包含一个数据以及若干指向子树的分支
l 结点拥有的子树数称为结点的度
u 度为0的结点称为叶结点
u 度不为0的结点称为分支结点
l 树的度定义为所有结点中的度的最大值
l 结点的直接后继称为该结点的孩子
u 相应的,该结点称为孩子的双亲
l 结点的孩子的孩子的.....称为该结点的子孙
u 相应的,该结点称为子孙的祖先
l 同一个双亲的孩子之间互称兄弟
l 树中结点的最大层次称为树的深度或高度
l 森林是由n(n>=0)棵互不相交的树组成的集合
在这里,我们用通用树结构来给大家介绍树的一些基本操作和操作实现。通用树的存储结构为:
这里介绍通用树的常用操作:
l 创建树
l 销毁树
l 清空树
l 插入结点到树中
l 删除结点
l 获取某个结点
l 获取根结点
l 获取树的高度
l 获取总结点数
l 获取树的度
l 输出树
代码总分为三个文件:
GTree.h : 放置功能函数的声明,以及树的声明,以及数据的声明
GTree.c : 放置功能函数的定义,以及树结点和组织链表结点的定义
Main.c : 主函数,使用功能函数完成各种需求,一般用作测试
整体结构图为:
这里详细说下插入结点操作,删除结点操作:
插入结点操作:
如图:
删除结点操作:
如图:
OK! 上代码:
GTree.h :
- #ifndef _GTREE_H_
- #define _GTREE_H_
- typedef void GTree;
- typedef void GTreeData;
- typedef void (GTree_Printf)(GTreeData*);
- GTree* GTree_Create();
- void GTree_Destroy(GTree* tree);
- void GTree_Clear(GTree* tree);
- int GTree_Insert(GTree* tree, GTreeData* data, int pPos);
- GTreeData* GTree_Delete(GTree* tree, int pos);
- GTreeData* GTree_Get(GTree* tree, int pos);
- GTreeData* GTree_Root(GTree* tree);
- int GTree_Height(GTree* tree);
- int GTree_Count(GTree* tree);
- int GTree_Degree(GTree* tree);
- void GTree_Display(GTree* tree, GTree_Printf* pFunc, int gap, char div);
- #endif
GTree.c :
- #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;
- };
- GTree* GTree_Create()
- {
- return LinkList_Create();
- }
- void GTree_Destroy(GTree* 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)
- {
- LinkList* list = (LinkList*)tree;
- int ret = (NULL!=list) && (NULL!=data) && (pPos<LinkList_Length(list));
- if(ret)
- {
- TLNode* trNode = (TLNode*)malloc(sizeof(TLNode));
- TLNode* cldNode = (TLNode*)malloc(sizeof(TLNode));
- TLNode* pNode = (TLNode*)LinkList_Get(list, pPos);
- GTreeNode* cNode = (GTreeNode*)malloc(sizeof(GTreeNode));
- ret = (NULL!=trNode) && (NULL!=cldNode) && (NULL!=cNode);
- 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(NULL != pNode)
- {
- cNode->parent = pNode->node;
- LinkList_Insert(pNode->node->child, (LinkListNode*)cldNode, LinkList_Length(pNode->node->child));
- }
- else
- {
- free(cldNode);
- }
- }
- else
- {
- free(trNode);
- free(cldNode);
- free(cNode);
- }
- }
- return ret;
- }
- static int recursive_height(GTreeNode* node)
- {
- int ret = 0;
- if(NULL != node)
- {
- 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;
- }
- return ret;
- }
- int GTree_Height(GTree* tree)
- {
- TLNode* trNode = (TLNode*)LinkList_Get(tree, 0);
- int ret = 0;
- if(NULL != trNode)
- {
- ret = recursive_height(trNode->node);
- }
- return ret;
- }
- static void recursive_delete(LinkList* list, GTreeNode* node)
- {
- if((NULL != list) && (NULL != node))
- {
- 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(node == trNode->node)
- {
- LinkList_Delete(list, i);
- free(trNode);
- index = i;
- break;
- }
- }
- if(0 <= index)
- {
- if(NULL != parent)
- {
- for(i=0; i<LinkList_Length(parent->child); i++)
- {
- TLNode* trNode = (TLNode*)LinkList_Get(parent->child, i);
- if(node == trNode->node)
- {
- LinkList_Delete(parent->child, i);
- free(trNode);
- break;
- }
- }
- }
- while(0 < LinkList_Length(node->child))
- {
- TLNode* trNode = (TLNode*)LinkList_Get(node->child, 0);
- recursive_delete(list, trNode->node);
- }
- LinkList_Destroy(node->child);
- free(node);
- }
- }
- }
- GTreeData* GTree_Delete(GTree* tree, int pos)
- {
- TLNode* trNode = (TLNode*)LinkList_Get(tree, pos);
- GTreeData* ret = NULL;
- if(NULL != trNode)
- {
- ret = trNode->node->data;
- recursive_delete(tree, trNode->node);
- }
- return ret;
- }
- GTreeData* GTree_Get(GTree* tree, int pos)
- {
- TLNode* trNode = (TLNode*)LinkList_Get(tree, pos);
- GTreeData* ret = NULL;
- if(NULL != trNode)
- {
- ret = trNode->node->data;
- }
- return ret;
- }
- GTreeData* GTree_Root(GTree* tree)
- {
- return GTree_Delete(tree, 0);
- }
- int GTree_Count(GTree* tree)
- {
- return LinkList_Length(tree);
- }
- static int recursive_degree(GTreeNode* node)
- {
- int ret = -1;
- if(NULL != node)
- {
- 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;
- }
- int GTree_Degree(GTree* tree)
- {
- TLNode* trNode = (TLNode*)LinkList_Get(tree, 0);
- int ret = -1;
- if(NULL != trNode)
- {
- ret = recursive_degree(trNode->node);
- }
- return ret;
- }
- static void recursive_display(GTreeNode* node, GTree_Printf* pFunc, int format, int gap, char div)
- {
- int i = 0;
- if((NULL != node) && (NULL != pFunc))
- {
- 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);
- }
- }
- }
- void GTree_Display(GTree* tree, GTree_Printf* pFunc, int gap, char div)
- {
- TLNode* trNode = (TLNode*)LinkList_Get(tree, 0);
- if((NULL != trNode) && (NULL != pFunc))
- {
- recursive_display(trNode->node, pFunc, 0, gap, div);
- }
- }
Main.c :
- #include <stdio.h>
- #include "GTree.h"
- void printf_data(GTreeData* data)
- {
- printf("%c", (int)data);
- }
- int main(void)
- {
- GTree* tree = GTree_Create();
- int i = 0;
- GTree_Insert(tree, (GTreeData*)'A', -1);
- GTree_Insert(tree, (GTreeData*)'B', 0);
- GTree_Insert(tree, (GTreeData*)'C', 0);
- GTree_Insert(tree, (GTreeData*)'D', 0);
- GTree_Insert(tree, (GTreeData*)'E', 1);
- GTree_Insert(tree, (GTreeData*)'F', 1);
- GTree_Insert(tree, (GTreeData*)'H', 3);
- GTree_Insert(tree, (GTreeData*)'I', 3);
- GTree_Insert(tree, (GTreeData*)'J', 3);
- printf("Tree Height: %d\n", GTree_Height(tree));
- printf("Tree Degree: %d\n", GTree_Degree(tree));
- printf("Full Tree:\n");
- GTree_Display(tree, printf_data, 2, '-');
- printf("Get Tree Data: \n");
- for(i=0; i<GTree_Count(tree); i++)
- {
- printf_data(GTree_Get(tree, i));
- printf("\n");
- }
- printf("Get Root Data: \n");
- printf_data(GTree_Root(tree));
- printf("\n");
- GTree_Delete(tree, 3);
- printf("After Deleting D: \n");
- GTree_Display(tree, printf_data, 2, '-');
- GTree_Clear(tree);
- printf("After Clearing Tree:\n");
- GTree_Display(tree, printf_data, 2, '.');
- GTree_Destroy(tree);
- return 0;
- }