Chinaunix首页 | 论坛 | 博客
  • 博客访问: 251541
  • 博文数量: 52
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1538
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-24 07:45
个人简介

生活就像海洋,只有意志坚强的人,才能到达彼岸。

文章存档

2013年(52)

分类: C/C++

2013-08-24 20:47:07

一、树的定义

1>定义

   树是一种非线性的数据结构,树是由n(n>=0)个结点组成的有限集合;如果n=0,称为空树;如

n>0,则:
    有一个特定的称之为根(root)的结点,它只有直接后继,但没有直接前驱;
    
    除根以外的其他结点划分为m(m>=0)个,互不相交的有限集合T0,T1,...,Tn-1,每个集合又是

一棵树,并且称之为根的子树(subTree).

2>树家族中的概念

    树的结点包含一个数据及若干指向子树的分支;

    结点拥有的子树称为结点的度:
        度为0的结点称为叶结点;

        度不为0的结点称为分支结点;

    树的度定义为所有结点中的度的最大值。

    结点的直接后继称为该结点的孩子,相应的,该结点称为孩子结点的双亲;

    结点的孩子的孩子的...称为该结点的子孙,相应的,该结点称为子孙的祖先;

    同一个双亲的孩子之间互称兄弟。

    结点的层次:根为第一层,根的孩子为第二层......树中结点的最大层次称为树的深度或高度。

    如果树中结点的各子树从左向右是有次序的,子树间不能互换位置,则称该树为有序树,否则为

无序树。

    森林是 由n(n>=0)棵互不相交的树组成的集合。

3>树的操作:

创建树、销毁树、清空树、插入结点、删除结点、获取结点、获取根结点、获取树的结点树、获取树

的高度、获取树的度。

4>树操作的实现

树在程序中表现为一种特殊的数据类型,树的操作在程序中的表现为一组函数。

Tree* Tree_Create();

void Tree_Destroy(Tree* tree);

void Tree_Clear(Tree* tree);

int Tree_Insert(Tree* tree,TreeNode* node,int pos);

TreeNode* Tree_Delete(Tree* tree,int pos);

TreeNode* Tree_Get(Tree* tree,int pos);

TreeNode* Tree_Root(Tree* tree);

int Tree_Height(Tree* tree);

int Tree_Count(Tree* tree);

int Tree_Degree(Tree* tree);

二、树的存储结构

无法直接用数组表示树的逻辑结构,但可以设计结构体数组对结点间的关系进行表述,利用链表组织

树中的各个结点;链表中的前后关系不代表结点间的逻辑关系,结点的逻辑关系由child数据域描述

child数据域保存其他结点的存储地址。

树结点结构体:

typedef struct _tag_GTreeNode GTreeNode;
struct _tag_GTreeNode
{
    GTreeData* data;
    GTreeNode* parent;
    LinkList* child;
};

链表结点结构体
typedef struct _tag_TLNode TLNode;
struct _tag_TLNode
{
    LinListNode* header;
    GTreeNode* node;
};

树中每一个结点包含一个指向父节点的指针。注意:树结点在链表中的位置不代表树的任何逻辑关

。本节中的树结构式一种通用的数据结构,利用链表组织树结点能够便利的存取结点,链表的维护

具有一定的复杂性。

通过链表的代码复用,通用树结构的实现代码如下:


点击(此处)折叠或打开

  1. /***********GTree.h***************************/
  2. #ifndef _GTREE_H_
  3. #define _GTREE_H_



  4. typedef void GTree;
  5. typedef void GTreeData;
  6. typedef void (GTree_Printf)(GTreeData*);

  7. GTree* GTree_Create();

  8. void GTree_Destroy(GTree* tree);

  9. void GTree_Clear(GTree* tree);

  10. int GTree_Insert(GTree* tree,GTreeData* data,int pPos);

  11. GTreeData* GTree_Delete(GTree* tree,int pPos);

  12. GTreeData* GTree_Get(GTree* tree,int pPos);

  13. GTreeData* GTree_Root(GTree* tree);

  14. int GTree_Height(GTree* tree);

  15. int GTree_Count(GTree* tree);

  16. int GTree_Degree(GTree* tree);

  17. void GTree_Display(GTree* tree,GTree_Printf* pFunc,int gap, char div);

  18. #endif


点击(此处)折叠或打开

  1. /*****************GTree.c*********************/
  2. #include <stdio.h>
  3. #include <malloc.h>
  4. #include "GTree.h"
  5. #include "LinkList.h"

  6. typedef struct _tag_GTreeNode GTreeNode;
  7. struct _tag_GTreeNode
  8. {
  9.     GTreeData* data;
  10.     GTreeNode* parent;
  11.     LinkList* child;
  12. };

  13. typedef struct _tag_TLNode TLNode;
  14. struct _tag_TLNode
  15. {
  16.     LinkListNode header;
  17.     GTreeNode* node;
  18. };

  19. static void recursive_display(GTreeNode* node,GTree_Printf* pFunc, int format,int gap,char div)
  20. {
  21.     int i = 0;
  22.     
  23.     if( (node != NULL) && (pFunc != NULL) )
  24.     {
  25.         for(i=0; i<format; i++)
  26.         {
  27.             printf("%c",div);    
  28.         }    
  29.         
  30.         pFunc(node->data);
  31.         
  32.         printf("\n");
  33.         
  34.         for(i=0; i<LinkList_Length(node->child); i++)
  35.         {
  36.             TLNode* trNode = (TLNode*)LinkList_Get(node->child,i);
  37.             
  38.             recursive_display(trNode->node,pFunc,format+gap,gap,div);    
  39.         }
  40.     }
  41. }
  42. static void recursive_delete(LinkList* list,GTreeNode* node)
  43. {
  44.     if( (list != NULL) && (node != NULL) )
  45.     {
  46.         GTreeNode* parent = node->parent;
  47.         int index = -1;
  48.         int i = 0;
  49.         
  50.         for(i=0; i<LinkList_Length(list); i++)
  51.         {
  52.             TLNode* trNode = (TLNode*)LinkList_Get(list,i);
  53.             
  54.             if( trNode->node == node)
  55.             {
  56.                 LinkList_Delete(list,i);
  57.                 
  58.                 free(trNode);
  59.                 
  60.                 index = i;
  61.                 
  62.                 break;    
  63.             }    
  64.         }
  65.         
  66.         if( index >= 0 )
  67.         {
  68.             if( parent != NULL )
  69.             {
  70.                 for(i=0; i<LinkList_Length(parent->child); i++)
  71.                 {
  72.                     TLNode* trNode = (TLNode*)LinkList_Get(parent->child,i);
  73.                     
  74.                     if( trNode->node == node)
  75.                     {
  76.                         LinkList_Delete(parent->child,i);
  77.                         
  78.                         free(trNode);
  79.                         
  80.                         break;    
  81.                     }    
  82.                 }    
  83.             }
  84.             
  85.             while( LinkList_Length(node->child) > 0 )
  86.             {
  87.                 TLNode* trNode = (TLNode*)LinkList_Get(node->child,0);
  88.                 
  89.                 recursive_delete(list,trNode->node);    
  90.             }    
  91.             
  92.             LinkList_Destroy(node->child);
  93.             
  94.             free(node);
  95.         }    
  96.     }
  97. }
  98. GTree* GTree_Create()
  99. {
  100.     return LinkList_Create();
  101. }

  102. void GTree_Destroy(GTree* tree)
  103. {
  104.     GTree_Clear(tree);
  105.     LinkList_Destroy(tree);
  106. }

  107. void GTree_Clear(GTree* tree)
  108. {
  109.     GTree_Delete(tree,0);
  110. }

  111. int GTree_Insert(GTree* tree,GTreeData* data,int pPos)
  112. {
  113.     LinkList* list = (LinkList*)tree;
  114.     int ret = (list != NULL) && (data != NULL) && (pPos < LinkList_Length(list));
  115.     if(ret)
  116.     {
  117.         GTreeNode* cNode = (GTreeNode*)malloc(sizeof(GTreeNode));
  118.         TLNode* trNode = (TLNode*)malloc(sizeof(TLNode));
  119.         TLNode* cldNode = (TLNode*)malloc(sizeof(TLNode));
  120.         TLNode* pNode = (TLNode*)LinkList_Get(list,pPos);
  121.         
  122.         ret = (cNode != NULL) && (trNode != NULL) && (cldNode != NULL);
  123.         if( ret )
  124.         {
  125.             cNode->data = data;
  126.             cNode->parent = NULL;
  127.             cNode->child = LinkList_Create();
  128.             
  129.             trNode->node = cNode;
  130.             cldNode->node = cNode;
  131.             
  132.             LinkList_Insert(list,(LinkListNode*)trNode, LinkList_Length(list));
  133.             
  134.             if( pNode != NULL )
  135.             {
  136.                 cNode->parent = pNode->node;
  137.                 
  138.                 LinkList_Insert(pNode->node->child,(LinkListNode*)cldNode,LinkList_Length(pNode->node->child));    
  139.             }
  140.             else
  141.             {
  142.                 free(cldNode);
  143.             }
  144.             
  145.                 
  146.         }
  147.         else
  148.         {
  149.             free(trNode);
  150.             free(cldNode);
  151.             free(cNode);    
  152.         }    
  153.     }
  154.     
  155.     return ret;
  156. }

  157. GTreeData* GTree_Delete(GTree* tree,int pos)
  158. {
  159.     TLNode* trNode = (TLNode*)(LinkList_Get(tree,pos));
  160.     GTreeData* ret = NULL;
  161.     
  162.     
  163.     if( trNode != NULL )
  164.     {
  165.         ret = trNode->node->data;
  166.         
  167.         recursive_delete(tree,trNode->node);
  168.     }
  169.     
  170.     return ret;
  171. }

  172. static int recursive_height(GTreeNode* node)
  173. {
  174.     int ret = 0;
  175.     
  176.     if( node != NULL )
  177.     {
  178.         int subHeight = 0;
  179.         int i= 0;
  180.         
  181.         for(i=0; i<LinkList_Length(node->child); i++)
  182.         {
  183.             TLNode* trNode = (TLNode*)LinkList_Get(node->child,i);
  184.             
  185.             subHeight =    recursive_height( trNode->node);
  186.             
  187.             if( ret < subHeight )
  188.             {
  189.                 ret = subHeight;    
  190.             }
  191.         }    
  192.         
  193.         ret = ret + 1;
  194.     }
  195.     
  196.     return ret;
  197. }

  198. static int recursive_degree(GTreeNode* node)
  199. {
  200.     int ret = 0;
  201.     
  202.     if( node != NULL )
  203.     {
  204.         int subDegree = 0;
  205.         int i = 0;
  206.         
  207.         ret = LinkList_Length(node->child);
  208.         
  209.         for(i=0; i<LinkList_Length(node->child); i++)
  210.         {
  211.             TLNode* trNode = (TLNode*)LinkList_Get(node->child ,i);
  212.             
  213.             subDegree = recursive_degree(trNode->node);
  214.             
  215.             if( ret < subDegree )    
  216.             {
  217.                 ret = subDegree;    
  218.             }
  219.         }    
  220.     }
  221.     
  222.     return ret;
  223. }


  224. GTreeData* GTree_Get(GTree* tree,int pos)
  225. {
  226.     
  227.     TLNode* trNode = (TLNode*)(LinkList_Get(tree,pos));
  228.     GTreeData* ret = NULL;
  229.     
  230.     
  231.     if( trNode != NULL )
  232.     {
  233.         ret = trNode->node->data;
  234.     }
  235.     
  236.     return ret;
  237. }

  238. GTreeData* GTree_Root(GTree* tree)
  239. {
  240.     return GTree_Get(tree,0);
  241. }

  242. int GTree_Height(GTree* tree)
  243. {
  244.     TLNode* trNode = (TLNode*)LinkList_Get(tree,0);
  245.     int ret = 0;
  246.     
  247.     if( trNode != NULL )
  248.     {
  249.         ret = recursive_height(trNode->node);        
  250.     }
  251.     return ret;
  252. }

  253. int GTree_Count(GTree* tree)
  254. {
  255.     return LinkList_Length(tree);
  256. }

  257. int GTree_Degree(GTree* tree)
  258. {
  259.     TLNode* trNode = (TLNode*)LinkList_Get(tree,0);
  260.     int ret = 0;
  261.     
  262.     if( trNode != NULL )
  263.     {
  264.         ret = recursive_degree(trNode->node);    
  265.     }
  266.     
  267.     return ret;
  268. }

  269. void GTree_Display(GTree* tree,GTree_Printf* pFunc,int gap, char div)
  270. {
  271.     TLNode* trNode = (TLNode*)LinkList_Get(tree,0);
  272.     
  273.     if( trNode != NULL )
  274.     {
  275.         recursive_display(trNode->node,pFunc,0,gap,div);    
  276.     }
  277. }


点击(此处)折叠或打开

  1. /******************main.c********************/
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "GTree.h"

  5. /* run this program using the console pauser or add your own getch, system("pause") or input loop */

  6. void printf_data(GTreeData* data)
  7. {
  8.     printf("%c ",(int)data);
  9. }

  10. int main(int argc, char *argv[])
  11. {
  12.     GTree* tree = GTree_Create();
  13.     int i = 0;
  14.     
  15.     GTree_Insert(tree, (GTreeData*)'A',-1);
  16.     GTree_Insert(tree, (GTreeData*)'B',0);
  17.     GTree_Insert(tree, (GTreeData*)'C',0);
  18.     GTree_Insert(tree, (GTreeData*)'D',0);
  19.     GTree_Insert(tree, (GTreeData*)'E',1);
  20.     GTree_Insert(tree, (GTreeData*)'F',1);
  21.     GTree_Insert(tree, (GTreeData*)'H',3);
  22.     GTree_Insert(tree, (GTreeData*)'I',3);
  23.     GTree_Insert(tree, (GTreeData*)'J',3);
  24.     
  25.     printf("Tree Degree: %d\n",GTree_Degree(tree));
  26.     
  27.     printf("Tree Height: %d\n",GTree_Height(tree));
  28.     
  29.     printf("Get Tree Data: \n");
  30.     
  31.     for(i=0; i<GTree_Count(tree); i++)
  32.     {
  33.         printf_data(GTree_Get(tree,i));    
  34.         
  35.     }
  36.     printf("\n");
  37.     
  38.     printf("Get Root Data: \n");
  39.     
  40.     printf_data(GTree_Root(tree));
  41.     printf("\n");
  42.     
  43.     GTree_Display(tree,printf_data,2,'*');
  44.     
  45.     
  46.     GTree_Delete(tree,3);
  47.     

  48.     
  49.     printf("After Delete D : \n");
  50.     GTree_Display(tree,printf_data,2,'-');
  51.     
  52.     GTree_Clear(tree);
  53.     
  54.     printf("After Clear: \n");
  55.     GTree_Display(tree,printf_data,2,'+');
  56.         
  57.     GTree_Destroy(tree);
  58.     
  59.     return 0;
  60. }


阅读(1632) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~