您的位置:首页 > 理论基础 > 数据结构算法

数据结构(25)树

2015-08-11 15:02 417 查看
今天来看大家介绍树,树是一种非线性的数据结构,树是由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 :

[cpp] view
plaincopy

#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 :

[cpp] view
plaincopy

#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 :



[cpp] view
plaincopy

#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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: