您好,欢迎来到二三娱乐。
搜索
您的当前位置:首页二叉树与森林的转换

二叉树与森林的转换

来源:二三娱乐

思路

  • 利用递归建立节点完成转换。首先我们观察二叉树的结构,包含第一个孩子,及其兄弟。关键在于:那么我们在构造递归时,每层recursion中都必须找到对应sibling和firstchild。对于双亲表示法,我们很难找到孩子,对于孩子表示法,我们很难找到双亲(因为找到双亲是找到本节点兄弟的唯一方法,或在传参时也传入父节点指针)。
  • 不同形式间转换的技巧。对于要被转换的结构,需要传入针对它单次recursion完成结构内部所有成员构造对应的转换的结构的信息。就能完成一层递归。同时应注意递归结束的条件。

孩子表示法生成二叉树算法

typedef struct BiTree{
    ElemType data;
    struct BiTree *firstchild, *sibling;
}BTnode, *BTree;

typedef struct Lnode{
    int child;
    struct Lnode *next;
}Lnode, *CList;
typedef struct Cbox{
    ElemType data;
    CList firstchild;
}Cbox, *Cnode;
typedef struct CTnode{
    Cnode node;
    int n, r;
}CTree;

void TransformChildTreeToBinaryTree(CTree CT, BTree &BT, int preroot, int root){
    if (root == -1){
        BT = NULL; return;
    }
    BT = (BTree)malloc(sizeof(BTnode));
    BT->data = CT.node[root].data;
    int rsave;
    if (CT.node[root].firstchild){
        rsave = CT.node[root].firstchild->child;
    }
    else{
        rsave = -1;
    }
    TransformChildTreeToBinaryTree(CT, BT->firstchild, root, rsave);
    if (preroot == -1){
        BT->sibling = NULL; return;
    }
    CList p = CT.node[preroot].firstchild;
    while (p && p->data != root){
        p = p->next;
    }
    if (p->next){
        rsave = p->next->child;
    }
    else{
        rsave = -1;
    }
    TransformChildTreeToBinaryTree(CT, BT->sibling, preroot, rsave);
    return;
}

孩子双亲表示法生成二叉树(类似于孩子表示法)

typedef struct BTnode{
    ElemType data;
    struct BTnode *firstchild, *sibling;
}BTnode, *BTree;

typedef struct Cnode{
    int child;
    struct Cnode *next;
}Cnode, *CList;
typedef struct CTnode{
    int parent;
    ElemType data;
    CList firstchild;
}CTnode, *CTbox;
typedef struct PCTnode{
    CTbox node;
    int r, n;
}PCTree;

void TransformPCTreeToBiTree(PCTree PC, BTree &BT, int root){
    if (root == -1){
        BT = NULL; return;
    }
    BT = (BTree)malloc(sizeof(BTnode));
    BT->data = PC.node[root].data;
    int rsave, tmp;
    if (PC.node[root].firstchild){
        rsave = PC.node[root].firstchide->child;
    }
    else{
        rsave = -1;
    }
    TransformPCTreeToBiTree(PC, BT->firstchild, rsave);
    tmp = PC.node[root].parent;
    if (tmp == -1){
        BT->sibling = NULL; return;
    }
    else{
        LList p = PC.node[tmp].firstchild;
        while (p && p->child != root){
            p = p->next;
        }
        if (p->next){
            rsave = p->next->child;
        }
        else{
            rsave = -1;
        }
        TransformPCTreeToBiTree(PC, BT->sibling, rsave);
        return;
    }
}

同构链式孩子表示法生成二叉树

typedef struct BTnode{
    ElemType data;
    struct BTnode *firstchild, *sibling;
}BTnode, *BTree;

#define DEGREE 5
typedef struct LCTnode{
    ElemType data;
    struct LCTnode *child[DEGREE];
}LCTnode, *LCTree;


BTree InitialTransLCTree2BiTree(LCTree root){
    if (!root){
        return NULL;
    }
    BTree BTroot = (BTree)malloc(sizeof(BTnode));
    BTroot->data = LCTree->data;
    BTroot->sibling = NULL;
    TransformLinkedChildTreeToBinaryTree(BTroot->firstchild, root, 0);
    return BTroot;
}
void TransformLinkedChildTreeToBinaryTree(BTree &BT, LCTree LCT, int i){
    if (i >= DEGREE || !LCT->child[i]){
        BT = NULL; return;
    }
    BT = (BTree)malloc(sizeof(BTnode));
    BT->data = LCT->child[i]->data;
    TransformLinkedChildTreeToBinaryTree(BT, LCT->sibling, i + 1);
    TransformLinkedChildTreeToBinaryTree(BT->child[i], LCT->firstchild, 0);
    return;
}

异构链式孩子表示法生成二叉树

typedef struct BTnode{
    ElemType data;
    struct BTnode *firstchild, *sibling;
}BTnode, *BTree;

#ifdef DEGREE
#undef DEGREE
#define DEGREE 5
#endif

typedef struct LCTnode{
    ElemType data;
    struct LCTnode * *child;
    int degree;
}LCTnode, *LCTree;

void TransformLCTree2BinaryTree(LCTree LCT, BTree &BT, int i){
    if (i >= LCT->degree || !LCT->child[i]){
        BT = NULL; return;
    }
    BT = (BTree)malloc(sizeof(BTnode));
    BT->data = LCT->child[i]->data;
    TransformLCTree2BinaryTree(LCT, BT->sibling, i + 1);
    TransformLCTree2BinaryTree(LCT->child[i], BT->firstchild, 0);
    return;
}

//Another Method:
void TransformLCTree2BinaryTree2(LCTree LCT, BTree &BT){
    if (!LCT->child[0]){
        BT = NULL; return;
    }
    BTree p, q;
    for (int i = 0; i < LCT->degree && LCT->child[i]; ++i){
        BTree q = (BTree)malloc(sizeof(BTnode));
        q->data = LCT->child[i]->data;
        q->sibling = NULL;
        q->firstchild = NULL;
        if (!BT){
            BT = q;
            p = q;
        }
        else{
            q->sibling = p->sibling; p->sibling = q;
            p = q;
        }
        TransformLCTree2BinaryTree2(LCT->child[i], q->firstchild);
        return;
    }
}

有两种方法的思路不同:前者是按单个节点完成递归,而后者则是按照层来递归(虽然二者都是深度优先),后者更像是图的遍历方法。

本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。

热门图文

Copyright © 2019-2025 yule263.com 版权所有 湘ICP备2023023988号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务