通用树--GTree(双亲孩子法)


//--  LinkList.h 
#ifndef _LINKLIST_H_
#define _LINKLIST_H_

typedef void LinkList;
typedef struct _tag_LinkListNode LinkListNode;
struct _tag_LinkListNode
{
	LinkListNode* next;
};
LinkList* LinkList_Create();

void LinkList_Destroy(LinkList* list);

int LinkList_Length(LinkList* list);

int LinkList_Insert(LinkList* list,LinkListNode* node,int pos);

LinkListNode* LinkList_Get(LinkList* list,int pos);

LinkListNode* LinkList_Delete(LinkList* list,int pos);

#endif

//--  LinkList.c
#include "LinkList.h"
#include <malloc.h>

typedef struct _tag_LinkList
{
	LinkListNode header;   //注意这里的位置顺序不要放反了,否则length就不对了 
	int length;	
}TLinkList;


LinkList* LinkList_Create()
{
	TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));
	if(ret != NULL)
	{
		ret->length = 0;
		ret->header.next = NULL;	
	}
	
	return ret;
}

void LinkList_Destroy(LinkList* list)
{
	free(list);
}
int LinkList_Length(LinkList* list)
{
	TLinkList* sList = (TLinkList*)list;
	int ret = -1;
	ret = (sList!=NULL);
	if(ret)
	{
		ret = sList->length;	
	}
	return ret;
}
int LinkList_Insert(LinkList* list,LinkListNode* node,int pos)
{
	int ret = -1;
	int i = 0;
	TLinkList* sList = (TLinkList*)list;
	ret = (sList!=NULL)&&(node!=NULL)&&(pos>=0)&&(pos<=sList->length);
	if(ret)
	{
		LinkListNode* current = (LinkListNode*)sList;
		for(i=0;(i<pos)&&(current->next!=NULL);i++)
		{
			current = current->next;	
		}
		node->next = current->next;
		current->next = node;
		sList->length++;	
	}
	return ret;
}
LinkListNode* LinkList_Get(LinkList* list,int pos)
{
	TLinkList* sList = (TLinkList*)list;
	LinkListNode* ret = NULL;
	int i = 0;
	if((sList!=NULL)&&(pos>=0)&&(pos<sList->length))
	{
		LinkListNode* current = (LinkListNode*)sList;
		for(i=0;i<pos;i++)
		{
			current = current->next;
		}
		ret = current->next;	
	}
	return ret;
}
LinkListNode* LinkList_Delete(LinkList* list,int pos)
{
	TLinkList* sList = (TLinkList*)list;
	LinkListNode* ret = NULL;
	int i = 0;
	if((sList!=NULL)&&(pos>=0)&&(pos<sList->length))
	{
		LinkListNode* current = (LinkListNode*)sList;
		for(i=0;i<pos;i++)
		{
			current = current->next;
		}
		ret = current->next;
		current->next = ret->next;    //这里要注意啊 
		sList->length--;
	}
	return ret;	
}

//--  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>   //NULL
#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)
{
	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 int recursive_degree(GTreeNode* node)
{
	int ret = 0;
	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;	
}
 
static int recursive_height(GTreeNode* node)
{
	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;
	}
	return ret;
}

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

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)
{
	int ret =0;
	LinkList* list = (LinkList*)tree;
	ret = (list!=NULL)&&(data!=NULL)&&(pPos<LinkList_Length(list));
	if(ret)
	{
		GTreeNode* cNode = (GTreeNode*)malloc(sizeof(GTreeNode));  //创建当前树节点 
		TLNode* trNode = (TLNode*)malloc(sizeof(TLNode));		   //向树链表中要插入的链表节点 
		TLNode* cldNode = (TLNode*)malloc(sizeof(TLNode));         //向父节点的孩子链表中要插入的链表节点 
		TLNode* pNode = (TLNode*)LinkList_Get(list,pPos);          //父节点中的孩子链表 
		
		ret = (cNode!=NULL)&&(trNode!=NULL)&&(cldNode!=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(cldNode);
			free(trNode);
			free(cNode);	
		} 	
	}	
	return ret;
}

GTreeData* GTree_Delete(GTree* tree,int pos)
{
	GTreeData* ret = NULL;
	TLNode* trNode = (TLNode*)LinkList_Get(tree,pos);
	if(trNode!=NULL)
	{
		ret = trNode->node->data;
		recursive_delete(tree,trNode->node);	
	}
	
	return ret; 
}

GTreeData* GTree_Get(GTree* tree,int pos)
{
	GTreeData* ret = NULL;
	TLNode* trNode = (TLNode*)LinkList_Get(tree,pos);
	if(trNode!=NULL)
	{
		ret = trNode->node->data;	
	}
	
	return ret;
}

GTreeData* GTree_Root(GTree* tree)
{
	return GTree_Get(tree,0);
}

int GTree_Height(GTree* tree)
{
	int ret = 0;
	TLNode* trNode = (TLNode*)LinkList_Get(tree,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)
{
	int ret = 0;
	TLNode* trNode = (TLNode*)LinkList_Get(tree,0);
	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);	
	}
}

//--  main.c

#include <stdio.h>
#include <stdlib.h>
#include "GTree.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

void printf_data(GTreeData* data)
{
	printf("%c",(int)data);
}

int main(int argc, char *argv[]) 
{
	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*)'G',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;
}









  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值