zoukankan      html  css  js  c++  java
  • 一步一步学数据结构之1--n(通用树)

     

           今天来看大家介绍树,树是一种非线性的数据结构,树是由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("
    ");
    		
    		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
    ", GTree_Height(tree));
    	printf("Tree Degree: %d
    ", GTree_Degree(tree));
    	printf("Full Tree:
    ");
    	
    	GTree_Display(tree, printf_data, 2, '-');
    	
    	printf("Get Tree Data: 
    ");
    	
    	for(i=0; i<GTree_Count(tree); i++)
    	{
    		printf_data(GTree_Get(tree, i));
    		printf("
    ");
    	}
    	
    	printf("Get Root Data: 
    ");
    	
    	printf_data(GTree_Root(tree));
    	printf("
    ");
    	
    	GTree_Delete(tree, 3);
    	printf("After Deleting D: 
    ");
    	GTree_Display(tree, printf_data, 2, '-');
    	
    	GTree_Clear(tree);
    	
    	printf("After Clearing Tree:
    ");
    	
    	GTree_Display(tree, printf_data, 2, '.');
    	
    	GTree_Destroy(tree);
    	
    	return 0;
    }


  • 相关阅读:
    poj 3243 Clever Y(BabyStep GiantStep)
    poj 2417 Discrete Logging
    poj 3481 Double Queue
    hdu 4046 Panda
    hdu 2896 病毒侵袭
    poj 1442 Black Box
    hdu 2815 Mod Tree
    hdu 3065 病毒侵袭持续中
    hdu 1576 A/B
    所有控件
  • 原文地址:https://www.cnblogs.com/riskyer/p/3253785.html
Copyright © 2011-2022 走看看