看数据结构写代码(29) 树的双亲表示法

源代码 网盘地址:点击打开链接

直接上代码:

// ParentTree.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <cstdlib>
#include "queue.h"
#include "stack.h"
#include <cstring>



#define TREE_INIT_SIZE 100//树的初识空间
#define TREE_ADD_SIZE  20 //当空间不足时,增加的空间
typedef char ElementType;

//树的双亲表示法
struct PTreeNode
{
	ElementType data;
	int parentIndex;//父亲节点 在 数组中的 索引
};

struct PTree
{
	PTreeNode * base;//节点的基址
	int rootIndex;//节点 在数组中的索引
	int len;//长度
	int size;//base 地址 空间的 大小
};

//初始化成一颗空树.
void treeInit(PTree  * tree){
	tree->base = NULL;
	tree->len = 0;
	tree->rootIndex = 0;
	tree->size = 0;//
}


//创建树 
E_State treeCreate(PTree * tree){
	treeInit(tree);
	tree->base = (PTreeNode *) malloc(sizeof(PTreeNode) * TREE_INIT_SIZE);
	tree->size = TREE_INIT_SIZE;//一定要记得加...
	if (tree->base == NULL)
	{
		return E_State_Error;
	}
	char data = ' ';
	printf("------------层序创建树(输入根节点数据,#代表空树)-------------\n");
	scanf("%c%*c",&data);
	if (data != '#')
	{
		tree->base[0].data = data;
		tree->base[0].parentIndex = -1;//根节点 无 双亲..
		tree->rootIndex = 0;
		tree->len = 1;
		LinkQueue queue;
		queueInit(&queue);
		//将 数据 和 数据的 索引 入队
		qElementType qData;
		qData.data = data;
		qData.index = 0;
		enqueue(&queue,qData);
		while (!queueEmpty(queue))
		{
			qElementType father;
			dequeue(&queue,&father);
			printf("--------请输入%c节点的 所有 孩子节点(输入exit 表示创建完毕)-------\n",father.data);
			char childArray[100];
			scanf("%s",childArray);
			if (strcmp(childArray,"exit") == 0)
			{
				break;
			}
			char * p = childArray;
			while (*p != '\0')
			{
				if (tree->len >= tree->size)//空间不足了
				{
					int newSize = tree->size + TREE_INIT_SIZE;
					tree->base = (PTreeNode *) realloc(tree->base,newSize);
					if (tree->base == NULL)
					{
						return E_State_Error;
					}
					tree->size = newSize;
				}
				int index = tree->len;
				tree->base[index].data = *p;
				tree->base[index].parentIndex = father.index;
				tree->len++;
				//将节点信息入队
				qData.data = *p;
				qData.index = index;
				enqueue(&queue,qData);
				p ++;
			}

		}
		queueDestory(&queue);
	}
	return E_State_Ok;
}

void treeClear(PTree * tree){
	free(tree->base);
	tree->base = NULL;
	tree->len = 0;
	tree->rootIndex = 0;
	tree->size = 0;
}

void treeDestory(PTree * tree){
	treeClear(tree);
}


void treeTraverse(PTree tree){
	printf("---------遍历 树---------------\n");
	for (int i = 0; i < tree.len; i++)
	{
		printf("%c\t",tree.base[i]);
	}
	printf("\n");
}

int treeLen(PTree tree){
	return tree.len;
}

bool treeIsEmpty(PTree tree){
	return tree.len == 0 ? true : false;
}

//获取 值 等于 data 节点的 索引
int treeGetDataIndex(PTree tree,ElementType data){
	for (int i = 0; i < tree.len; i++)
	{
		if (tree.base[i].data == data)
		{
			return i;
		}
	}
	printf("%c 节点不存在\n",data);
	return -1;//-1 表示没找到
}
//打印 值 等于 childData的 父节点
void treeGetFather(PTree tree,ElementType childData){
	int index = treeGetDataIndex(tree,childData);
	if (index != -1)
	{
		int fatherIndex = tree.base[index].parentIndex;//找父亲在数组中的 索引..
		if (fatherIndex != -1)
		{
			printf("%c 节点 的 父亲是 :%c\n",childData,tree.base[fatherIndex].data);
		}
		else
		{
			printf("根节点无父亲\n");
		}
	}
}
//打印值 等于 fatherData 的 孩子节点
void treeGetAllChild(PTree tree,ElementType fatherData){
	int fatherIndex = treeGetDataIndex(tree,fatherData);
	if (fatherIndex != -1)
	{
		printf("%c孩子节点是:",fatherData);
		for (int i = 0; i < tree.len; i++)
		{
			PTreeNode node = tree.base[i];
			if (node.parentIndex == fatherIndex)
			{
				printf("%c\t",node.data);
			}
		}
		printf("\n");
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	PTree tree;
	treeCreate(&tree);
	treeTraverse(tree);
	int len = treeLen(tree);
	char * isEmpty = treeIsEmpty(tree) ? "是" : "不是";
	treeGetFather(tree,'i');
	treeGetAllChild(tree,'b');
	treeDestory(&tree);
	return 0;
}
运行截图:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值