【数据结构X.5】代码实现 树和森林的双亲表示法,左孩子右兄弟表示法,创建树的左孩子右兄弟二叉树以及二叉树到树的双亲表示法的转换思路和算法

32 篇文章 0 订阅
16 篇文章 1 订阅

主题:

  1. 树和森林的双亲表示法,
  2. 树的左孩子右兄弟表示法
  3. 创建树的左孩子右兄弟二叉树
  4. 二叉树到树的双亲表示法的转换思路和算法

后续文章:

【数据结构】代码实现:左孩子右兄弟表示法转换为树的双亲表示法,左孩子右兄弟表示法转化为树的孩子兄弟链表表示法,树的双亲表示法转化为左孩子右兄弟的二叉树表示法

树和森林生成二叉树算法:

在这里插入图片描述

数据结构定义:

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

输入:

1
2
5
-1
6
-1
-1
3
-1
4
7
-1
8
-1
9
10
-1
-1
-1
-1
-1

函数代码:

Trees.h
#include <iostream>
#define MAX_SIZE 50
#include <stack>
#include <queue>
typedef struct ForestNode
{
    int data;
    struct ForestNode *lchild, *rbrother;
} ForestNode, *ForestHead;

/***
 * 树的前序遍历建立森林
 */
ForestHead CreateForestHead(ForestHead fr, bool isRoot)
{
    if (isRoot)
        std::cout << "请输入第一棵树根节点,-1标识空:";
    int data;
    fr = (ForestNode *)malloc(sizeof(ForestNode));
    std::cin >> data;
    fr->lchild = NULL;
    fr->rbrother = NULL;
    fr->data = data;
    if (data != -1)
    {
        bool isRoot = false;
        std::cout << "请输入" << data << "的首个孩子:";
        fr->lchild = CreateForestHead(fr->lchild, isRoot);
        std::cout << "请输入" << data << "的相邻兄弟:";
        fr->rbrother = CreateForestHead(fr->rbrother, isRoot);
    }
    return fr;
}

/***
 * 双亲表示法
 */
typedef struct TreeNode
{
    int valid = 0;  //该节点是否存储了父节点信息,如果没有,那么只是跳转指针,存储的是兄弟信息
    int parent = 0; //-1表示无父节点,其他表示指向的父节点
} TreeNode;

typedef struct Forest
{
    TreeNode f[MAX_SIZE];
} Forest; //森林的数列定义

/***
 * 将左孩子,右兄弟的存储方式的树,转化为双亲表示法
 */
void TransChildBrother2PrentArray(ForestHead fr, Forest *farray)
{
    if (fr)
    {
        TransChildBrother2PrentArray(fr->lchild, farray);
        if (fr->data != -1)
        {
            //std::cout << fr->data << "\t左孩子:" << fr->lchild->data << "\t右兄弟: " << fr->rbrother->data << std::endl;
            if (fr->rbrother->data != -1) //有了兄弟,记录类型为指针,指向第一个兄弟,
            {
                farray->f[fr->rbrother->data].valid = 0;
                farray->f[fr->rbrother->data].parent = fr->data;
            }
            if (fr->lchild->data != -1) //有了孩子,记录类型为真实值,孩子的parent置为父亲值
            {
                farray->f[fr->lchild->data].valid = 1;
                farray->f[fr->lchild->data].parent = fr->data;
            }
        }
        TransChildBrother2PrentArray(fr->rbrother, farray);
    }
}

/***
 * 把树链表转换为双亲表示法
 * 
 * 如果树有左孩子,那么左孩子的父节点就是双亲节点
 * 如果树有右孩子,那么说明树的父节点也是右孩子父节点
 * 最好用中序遍历二叉树,这样会先遍历全部的孩子节点
 * 
 * 中序遍历:5 6 2 3 7 8 10 9 4 1
 * 
 */
void GetParentArrayTreeList(ForestHead fr, Forest *farray, int nodeNum)
{
    TransChildBrother2PrentArray(fr, farray); //将左孩子,右兄弟的存储方式的树,转化为双亲表示法
    std::cout<<"将左孩子,右兄弟的存储方式的树,转化为双亲表示法:\n";
    for (int i = 1; i <= nodeNum; i++)
    {
        if (farray->f[i].valid != 0 && farray->f[i].valid != 1) //进行迭代,如果是树的根节点,有效位和双亲标志-1
        {
            farray->f[i].valid = -1;
            farray->f[i].parent = -1;
        }
        while (farray->f[i].valid == 0) //当有效位为0时,根据兄弟节点,去查找父亲节点值,直到找到为止。
        {
            if (farray->f[farray->f[i].parent].valid == 1)
                farray->f[i].valid = 1;
            farray->f[i].parent = farray->f[farray->f[i].parent].parent;
        }
        std::cout << "数据" << i << "指向:\t" << farray->f[i].parent << "\t是否指向父节点: " << farray->f[i].valid << std::endl;
    }
}


调用代码

Trees_use.cpp
#include"Trees.h"

int main()
{
   ForestHead tr = NULL;
    tr = CreateForestHead(tr, true); // 根据左孩子,右节点的规则创建树;
    Forest *farray = (Forest *)malloc(sizeof(Forest));
    GetParentArrayTreeList(tr, farray,10);//转化上面的树为 孩子双亲表示法
}

左孩子右节点转化为孩子双亲表示法思路:

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

最后得到结果,符合树的结构:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值