31 树的存储结构二

DIsplay() 递归显示 :图示

请添加图片描述

求树的高度时,递归的技巧

请添加图片描述

在递归的过程中:ret单独和任意一个子树的子高度比较,如果ret<max,ret=max -------------

注意:组织链表和子链表的【元素类型】都是TLNode*
链表都要先通过TLNode这一层,然后再到GTreeNode那一层

最终代码:

GTree.h

#pragma once

typedef void GTree;
typedef void GTreeData;
typedef void (GTree_Printf)(GTreeData*);

GTree* GTree_Create();
void GTree_Destory(GTree* tree);
void GTree_Clear();
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);

GTree.c

#include "GTree.h"
#include <stdio.h>
#include "LinkList.h"
#include <malloc.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 int recursive_degree(GTreeNode* node){
	int ret = -1;
	int i = 0;
	
	if (node) {
		ret = LinkList_Length(node->child);

		for (i = 0; i < LinkList_Length(node->child); i++)
		{
			TLNode* cldNode = LinkList_Get(node->child, i);
			int subDegree = recursive_degree(cldNode->node);
			if (ret < subDegree) {
				ret = subDegree;
			}
		}
	}

	return ret;
}

static void recursive_display(GTreeNode* node, GTree_Printf* pfunc, int format, int gap,char div) {
	int i = 0;

	if (node && 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);
		}
	}
}

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) {
				for ( i = 0; i < LinkList_Length(parent->child); i++)
				{
					TLNode* trNode = LinkList_Get(parent->child, i);
					if (trNode->node == node) {
						LinkList_Delete(parent->child, i);//父节点的child链表中删除此节点
						free(trNode);
						break;
					}
				}
			}

			while (LinkList_Length(node->child))
			{
				TLNode* trNode = LinkList_Get(node->child, 0);//找到当前节点的child链表中的所有GTreeNode*
				recursive_delete(list, trNode->node);//递归上面的做法---
			}

			LinkList_Destory(node->child);

			free(node);
		}
	}
}

static int recursive_height(GTreeNode* node) {
	int ret = 0;

	if (node) {
		int subHeight = 0;
		int i = 0;

		for ( i = 0; i < LinkList_Length(node->child); i++)
		{
			TLNode* trNode = LinkList_Get(node->child, i);

			subHeight = recursive_height(trNode->node);

			if (ret < subHeight) {
				ret = subHeight;
			}
		}

		ret += 1;
	}

	return ret;
}

GTree * GTree_Create()
{
	return LinkList_Create(); //树:其实就是一个单链表
}

void GTree_Destory(GTree * tree)
{
	GTree_Clear(tree);
	LinkList_Destory(tree);
}

void GTree_Clear(GTree* tree)
{
	GTree_Delete(tree, 0);
}

//pPos为父节点在组织链表中的序号
int GTree_Insert(GTree * tree, GTreeData * data, int pPos)
{
	LinkList* list = (LinkList*)tree;
	int ret = (list != NULL) && (data != NULL) && (pPos < LinkList_Length(list));

	if (ret) {
		TLNode* trNode = (TLNode*)malloc(sizeof(TLNode)); //添加到组织链表的 节点
		TLNode* cldNode = (TLNode*)malloc(sizeof(TLNode));//添加到子链表的 节点
		GTreeNode* cNode = (GTreeNode*)malloc(sizeof(GTreeNode));//GTreeNode
		
		TLNode* pNode = LinkList_Get(list, pPos);//组织链表中的父节点

		ret = (trNode != NULL) && (cldNode != NULL) && (cNode != NULL);

		if (ret) {
			cNode->data = data;
			cNode->parent = NULL;
			cNode->child = LinkList_Create();//创建子链表

			//两个链表节点中的node指针赋值
			trNode->node = cNode;
			cldNode->node = cNode;

			LinkList_Insert(list, (LinkListNode*)trNode, LinkList_Length(list));//插入到组织链表

			if (pNode) {
				cNode->parent = pNode->node;
				LinkList_Insert(pNode->node->child, (LinkListNode*)cldNode, LinkList_Length(pNode->node->child));//插入到父节点的子链表中
			}
		}
		else
		{
			free(trNode);
			free(cldNode);
			free(cNode);
		}
	}

	return 0;
}

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)
{
	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 = LinkList_Get(tree, 0);
	int ret;

	if (trNode) {
		ret = recursive_height(trNode->node);
	}

	return ret;
}

int GTree_Count(GTree * tree)
{
	return LinkList_Length(tree);
}

int GTree_Degree(GTree * tree)
{
	TLNode* trNode = LinkList_Get(tree, 0);
	int ret = -1;

	if (trNode) {
		ret = recursive_degree(trNode->node);
	}
	
	return ret;
}

void GTree_Display(GTree * tree, GTree_Printf * pFunc, int gap, char div)
{
	TLNode* trNode = LinkList_Get(tree, 0);

	if (trNode && pFunc) {
		recursive_display(trNode->node, pFunc, 0, gap, div);
	}
}

main.c

#include "GTree.h"
#include <stdio.h>
void printf_data(GTreeData* data) {
	printf("%c", (char)data);
}
int main() {
	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_Destory(tree);
}

在这里插入图片描述

小结

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值