树和二叉树的转换

树的表示法

  • 图像的表示法
    双亲表示法:数据 双亲
    孩子表示法:数据 孩子
    孩子兄弟表示法:长子 数据 兄弟
    在这里插入图片描述

  • 括号表示法
    在这里插入图片描述

  • 遍历表示法
    前序遍历
    中序遍历
    后序遍历
    层序遍历

双亲表示法

在这里插入图片描述

孩子表示法

在这里插入图片描述

孩子兄弟表示法

  • 结构示意图
    在这里插入图片描述
    将父子结点转为兄弟结点
    在这里插入图片描述
    进一步操作,将B、C、D的父子节点变换为兄弟结点
    在这里插入图片描述

  • 树结点

    typedef struct CSNode{
        Element data;                   //结点数据域
        struct CSNode * friendChild;    //长子
        struct CSNode * nextSibling;    //兄弟
    }CSNode, * CSTree;
    

    优点:
    他和二叉树的二叉链表表示完全一样,便于将一般的树结构转为二叉树进行处理

树和二叉树的相互转换 - 孩子兄弟表示法

左图是原树;右图是转化之后的树
在这里插入图片描述在这里插入图片描述

孩子兄弟表示法基本操作

#define NAME_SIZE   255
/** 数据元素 */
typedef struct
{
    int id;
    char name[NAME_SIZE];
}ElementType;

/** 孩子兄弟结点 */
typedef struct cbNode{
    ElementType data;                  //数据域
    struct cbNode * firstChild;       //长子结点
    struct cbNode * nextSibling;      //兄弟结点
}CBNode, * CBTree;  // *CBTree 二级指针

/** 初始化空树 */
void InitCBTree(CBTree * tree)
{
    *tree = (CBTree)malloc(sizeof(CBNode));
    (*tree)->firstChild = NULL;
    (*tree)->nextSibling = NULL;
}

/** 构造树 */
static int id = 0;
void CreateCBTree(CBNode ** node)
{
    char inputName[255];
    gets(inputName);
    //判断用户输入的是否是回车键
    if(strcmp(inputName, "\0") == 0) return;
    if(*node == NULL)
    {
        *node = (CBNode *)malloc(sizeof(CBNode));
        (*node)->firstChild = NULL;
        (*node)->nextSibling = NULL;
    }
    //为结点赋值
    (*node)->data.id = ++id;
    strcpy((*node)->data.name, inputName);
    //分别遍历输入长子结点和兄弟结点
    printf("请输入长子结点:");
    CreateCBTree(&((*node)->firstChild));
    printf("请输入兄弟结点:");
    CreateCBTree(&((*node)->nextSibling));
}

/** 先序遍历 */
void PreOrderCBTree(CBNode * node)
{
    if(node != NULL)
    {
        printf("[%d, %s] ", node->data.id, node->data.name);
        CBNode * p = node->firstChild;
        PreOrderCBTree(p);  //访问长子结点
        while(p)
        {
            p = p->nextSibling;    //访问兄弟结点
            PreOrderCBTree(p);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值