尘叶心繁

发表于:2019/8/23 9:47

【Note】:1,在声明结构体的时候,自己取的别名自己是不能用的

                2,可以通过偏移指针位数来获取数据

封装树头文件

Demo26.h

#ifndef _LINK_TREE_H_
#define _LINK_TREE_H_
#define LINK_TO_ELEM(link,elem_type,mem_name) \
	((elem_type*)((unsigned char*)link - (unsigned char*)(&((elem_type*)NULL)->mem_name)));
typedef struct tree_link
{
	struct tree_link* parent; //指向它的父节点
	struct tree_link* children;//指向它的子节点
	struct tree_link* brother;//指向它的兄弟节点

}treelink,*ztreelink;
typedef struct Tree_Master
{
	int num;
	char name[16];

	treelink link;
}TreeMaster;
TreeMaster* alloc_item_node(const char* name);
//添加节点
void link_parent(ztreelink parent, ztreelink children);
//删除节点
void link_remove(ztreelink node);
//遍历节点
void ideration(ztreelink parent, char* oneparentsname);
#endif

封装树的c文件

Demo26.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Demo26.h"
#define my_free free

TreeMaster* alloc_item_node(const char* name) {
	TreeMaster* tree = malloc(sizeof(TreeMaster));
	memset(tree, 0, sizeof(TreeMaster));
	strcpy(tree->name, name);
	(&(tree)->link)->brother = NULL;
	(&(tree)->link)->children = NULL;
	(&(tree)->link)->parent = NULL;
	return tree;
}
void link_parent(ztreelink parent, ztreelink children)
{
	//给子节点付parent
	children->parent = parent;
	if (parent == NULL)
	{
		return;
	}
	//用一个walk接收parent下子节点的地址
	ztreelink* walk = &((parent)->children);
	//循环找到最后一个
	while (*walk)
	{
		walk = &(*walk)->brother;
	}
	//添加该子节点
	*walk = children;
}
void ideration(ztreelink lord,char* oneparentsname)
{
	if (lord == NULL)
	{
		return;
	}
	TreeMaster* one = LINK_TO_ELEM(lord, TreeMaster, link);

	if (oneparentsname != ""&& oneparentsname != NULL)
	{
		printf("parents: %s;children: %s; \n", oneparentsname, one->name);
	}
	else
	{
		printf("king: %s \n", one->name);
	}
	ztreelink* all = &((lord)->children);

	while (*all)
	{
		//获取父节点数据
		one = LINK_TO_ELEM(&(*(*all)->parent), TreeMaster, link);
		//获取父节点name数据
		char* parentsname = one->name;
		//获取子节点数据
		one = LINK_TO_ELEM(*all, TreeMaster, link);
		//获取子节点数据
		printf("parents: %s;children: %s; \n", parentsname, one->name);
		
		if ((*all)->children!=NULL)
		{
			ideration((*all)->children, one->name);
		}
		all = &(*all)->brother;
		

	}

}
void link_remove(ztreelink node) 
{
	ztreelink* walk = node->parent->children;
	ztreelink* tbother = node->brother;
	TreeMaster* one;
	while (*walk)
	{
		if (*walk==node)
		{
			if (*tbother)
			{
				*walk = *tbother;
			}
			else
			{
				*walk = NULL;
			}
			break;
		}
		*walk = (*walk)->brother;
	}
	TreeMaster* one = LINK_TO_ELEM(node, TreeMaster, link);
	//将数据模块直接性清理掉
	my_free(one);
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Demo26.h"

int main()
{
	ztreelink node1 = NULL;
	TreeMaster* root = alloc_item_node("A");
	node1 = &root->link;
	
	TreeMaster* root1 = alloc_item_node("B");
	TreeMaster* root2 = alloc_item_node("C");
	TreeMaster* root3 = alloc_item_node("D");

	link_parent(node1, &root1->link);
	link_parent(node1, &root2->link);
	link_parent(&root2->link, &root3->link);
	
	ideration(&root2->link,"");

	system("pause");
	return 0;
}


请诸位自行测试。

关于TNBLOG
TNBLOG,技术分享
App store Android
精彩评论
{{item.replyName}}
{{item.content}}
{{item.time}}
{{subpj.replyName}}
@{{subpj.beReplyName}}{{subpj.content}}
{{subpj.time}}
猜你喜欢