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