数据结构-树的基本操作

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

 

posted @ 2016-04-26 19:02  __小火车  阅读(935)  评论(0编辑  收藏  举报