二叉树与森林的转换

思路

  • 利用递归建立节点完成转换。首先我们观察二叉树的结构,包含第一个孩子,及其兄弟。关键在于:那么我们在构造递归时,每层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;
    }
}

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355

推荐阅读更多精彩内容

  • 树的概述 树是一种非常常用的数据结构,树与前面介绍的线性表,栈,队列等线性结构不同,树是一种非线性结构 1.树的定...
    Jack921阅读 4,457评论 1 31
  • 四、树与二叉树 1. 二叉树的顺序存储结构 二叉树的顺序存储就是用数组存储二叉树。二叉树的每个结点在顺序存储中都有...
    MinoyJet阅读 1,537评论 0 7
  • 1 序 2016年6月25日夜,帝都,天下着大雨,拖着行李箱和同学在校门口照了最后一张合照,搬离寝室打车去了提前租...
    RichardJieChen阅读 5,105评论 0 12
  • 二叉树的定义#### 二叉树是n(n>=0)个具有相同类型的元素的有限集合,当n=0时称为空二叉树,当n>0时,数...
    kylinxiang阅读 1,401评论 0 2
  • 当我刷新淘宝收藏品,傻了。。涨价了?!翻了一翻。。肠子那个悔呐😞😞😞同样的产品,本来可以买便宜点的,这下可好,也不...
    薛先生阅读 348评论 0 1