树的双亲表示法&孩子表示法代码实现

双亲表示法

  • 双亲存储结构是一种顺序存储结构,用一组连续空间存储树的所有结点,同时在每个结点中附设一个伪指针指示其双亲结点的位置(因为除了根结点以外,每个结点只有唯一的双亲结点,将根结点的双亲结点位置设置为特殊值-1)。
    在这里插入图片描述
  • 优点:查指定结点的双亲很方便。
  • 缺点:查指定结点的孩子只能从头遍历。

双亲存储结构的类型声明

#define MAX_TREE_SIZE 100 //树中最多结点数
typedef struct //树的结点定义
{
	ElemType data; //数据元素
	int parent; //双亲位置域
}PTNode;
typedef struct //树的类型定义
{
	PTNode nodes[MAX_TREE_SIZE]; //双亲表示
	int n; //结点数
}PTree;

增加一个结点

  • 只需在空白处写入新结点的值并且记录它和双亲的关系。
  • 新增的数据元素无需按逻辑上的次序存储。

删除一个结点

  • 方案一:将要删除的结点的双亲结点的“指针”设为-1,这就表示该位置是空的。(空数据会导致遍历过程更慢)
  • 方案二:把尾部的数据往上移,填充要删除的那一行的数据。
    在这里插入图片描述

区别树的顺序存储结构与二叉树的顺序存储结构

  • 在树的顺序存储结构中,数组下标代表结点的编号,下标中所存的内容指示了结点之间的关系。而在二叉树的顺序存储结构中,数组下标既代表了结点的编号,又指示了二叉树中各结点之间的关系。当然二叉树属于树,因此二叉树都可以用树的存储结构来存储,但树却不都能用二叉树的存储结构来存储。

代码实现

#include<stdio.h>
#define MAX_TREE_SIZE 100 //树中最多结点数
#define NodeNum 13 //总的结点数
typedef char ElemType;
typedef struct //树的结点定义
{
	ElemType data; //数据元素
	int parent; //双亲位置域
}PTNode;
typedef struct //树的类型定义
{
	PTNode nodes[MAX_TREE_SIZE]; //双亲表示
	int n; //结点数
}PTree;

void CreateTree(PTree& t)
{
	int i, loc;
	ElemType ch;
	for (i = 0; i < NodeNum; i++)
	{
		printf("输入结点信息:");
		scanf("%c", &ch);
		scanf("%c", &ch);
		t.nodes[i].data = ch;
		printf("输入对应双亲的位置下标:");
		scanf("%d", &loc);
		t.nodes[i].parent = loc;
		printf("\n");
	}
}

int main()
{
	PTree t;
	int i, j;
	CreateTree(t);
	printf("输出各结点的连接情况:\n");
	for (i = 0; i < NodeNum; i++)
	{
		printf("%c", t.nodes[i].data);
		for (j = 0; j < NodeNum; j++)
		{
			if (t.nodes[j].parent == i) printf(" -%c", t.nodes[j].data);
		}
		printf("\n");
	}
	return 0;
}

运行结果

在这里插入图片描述
在这里插入图片描述

孩子表示法

孩子链存储结构的类型声明

typedef struct
{
	int child; //孩子结点在数组中的位置
	struct CTNode *next; //下一个孩子
}CTNode;

typedef struct
{
	ElemType data;
	struct CTNode *firstChild; //第一个孩子
}CTBox;

typedef struct
{
	CTBox nodes[MAX_TREE_SIZE];
	int n,r; //结点数和根的位置
}CTree;

按各个结点的度设计结构

  • 孩子表示法是将每个结点的孩子结点都用单链表链接起来形成一个线性结构,此时n个结点就有n个孩子链表(叶子结点的孩子链表为空表)。
    在这里插入图片描述
  • 优点:寻找子女的操作非常直接
  • 缺点:寻找双亲的操作需要遍历n个结点中孩子链表指针域所指向的n个孩子链表。

代码实现

#include<stdio.h>
#include<malloc.h>
#define MAX_TREE_SIZE 100
#define NodeNum 11
typedef char ElemType;
typedef struct CTNode //孩子结点
{
	int child; //孩子结点在数组中的位置
	struct CTNode* next; //下一个孩子
}CTNode;

typedef struct //顺序存储表
{
	ElemType data;
	struct CTNode* firstChild; //第一个孩子
}CTBox;

typedef struct
{
	CTBox nodes[MAX_TREE_SIZE];
	int n, r; //结点数和根的位置
}CTree;

void CreateBox(CTree &t)
{
	int i;
	ElemType ch;
	printf("输入结点信息:");
	for (i = 0; i < NodeNum; i++)
	{
		scanf("%c", &ch);
		t.nodes[i].data = ch;
		t.nodes[i].firstChild = NULL;
	}

}

void CreateNodes(CTree& t,ElemType ch, int num)
{
	CTNode* p, * r = t.nodes[0].firstChild;
	int i, j, k;
	while (num--)
	{
		p = (CTNode*)malloc(sizeof(CTNode));
		p->next = NULL;
		printf("输入孩子结点的编号:");
		scanf("%d", &i);
		for (j = 0; j < NodeNum; j++)
			if (t.nodes[j].data == ch) k = j;
		if (i != k)
		{
			p->child = i;
			if (t.nodes[k].firstChild == NULL)
			{
				t.nodes[k].firstChild = p;
				r = p;
			}
			else
			{
				r->next = p;
				r = p;
			}
		}
	}
}


int main()
{
	CTree t;
	CTNode* p;
	int i, num;
	CreateBox(t);
	printf("\n");
	for (i = 0; i < NodeNum; i++)
	{
		printf("创建结点%c的孩子结点\n", t.nodes[i].data);
		printf("输入要创建的孩子结点个数:");
		scanf("%d", &num);
		CreateNodes(t, t.nodes[i].data, num);
		printf("\n");
	}

	printf("输出各结点的连接情况:\n");
	for (i = 0; i < NodeNum; i++)
	{
		p = t.nodes[i].firstChild;
		printf("%d(%c)", i, t.nodes[i].data);
		while (p != NULL)
		{
			printf("-%d(%c) ", p->child, t.nodes[p->child].data);
			p = p->next;
		}
		printf("\n");
	}
	return 0;
}

运行结果

在这里插入图片描述

  • 19
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值