icoding | 树转二叉树

一、题目 

树转二叉树

使用队列,编写transfrom函数,将普通树转换成对应的二叉树。

二叉树的相关定义如下:

typedef int DataType;

typedef struct Node {

    DataType data;

    struct Node* left;

    struct Node* right;

} BiTNode, *BiTree;

普通树结点的定义如下:

#define MAX_CHILDREN_NUM 5

struct _CSNode {

    DataType data;

    struct _CSNode *children[MAX_CHILDREN_NUM];

};

typedef struct _CSNode CSNode;

其中,子树的根结点的指针存放在children数组的前 k 个元素中,即如果children[i]的值为NULL,而children[i-1]不为NULL,则表明该结点只有 i 棵子树,子树根结点分别保存在children[0]至children[i-1]中。

队列相关定义及操作如下:

struct __Queue {

    int i, j; //指向数组内元素的游标

    void **array;

};

typedef struct __Queue Queue;

Queue* create_queue(); //创建队列

bool is_empty_queue(Queue *tree); //队为空返回true,不为空时返回false

void* del_queue(Queue *tree); //结点指针出队

void add_queue(Queue *tree, void *node); //结点指针入队

void free_queue(Queue *tree); //释放队列

transform函数定义如下:

BiTNode* transform(CSNode *root);

其中 root 为普通树的根结点,函数返回该树对应二叉树的根结点。

二、算法 

BiTNode* transform(CSNode* root) {
    if (!root) return NULL;
        
    /* 生成二叉树的根结点 */
    BiTree broot = (BiTree)malloc(sizeof(struct Node));
    broot->data = root->data;
    broot->left = broot->right = NULL;
    
    /* 创建存储树和二叉树结点的队列 */
    Queue * queue = create_queue();
    Queue * bqueue = create_queue();
    /* 令两个根结点入队 */
    add_queue(queue, root);
    add_queue(bqueue, broot);
    
    while (!is_empty_queue(queue)) {
        /* 从两个队列中分别取出一个结点 */
        CSNode * node = del_queue(queue);
        BiTree Bnode = del_queue(bqueue);
        
        int i;
        BiTree former = NULL;
        /* 遍历node结点的所有孩子 */
        for (i = 0; i < MAX_CHILDREN_NUM; i++) {
            if (node->children[i]) {
                /* 生成相应的二叉树结点 */
                BiTree bnode = (BiTree)malloc(sizeof(BiTNode));
                bnode->left = bnode->right = NULL;
                bnode->data = node->children[i]->data;
                
                if (i == 0) /* node结点的第一个孩子成为Bnode结点的左孩子 */
                    Bnode->left = bnode;
                else /* 后面的孩子结点成为前面结点的右孩子 */
                    former->right = bnode;
                former = bnode;
                
                /* 将处理完成的结点入队 */
                add_queue(queue, node->children[i]);
                add_queue(bqueue, bnode);
            }
        }
    }
    free(queue->array);
    free(queue);
    free(bqueue->array);
    free(bqueue);
    return broot;
}

三、过程演示

创建存储树和二叉树结点的队列,并且令两个根结点入队。

随后取出根结点,对结点A的所有孩子进行处理,具体过程如下:

 

 

此时,结点A的孩子已经全部处理完毕。

令结点B出队,接下来进行对结点B的孩子的处理,具体过程如下:

  

 此时,结点B的孩子已经全部处理完毕。

令结点C出队,接下来进行对结点C的孩子的处理,具体过程略。

队空代表所有结点的孩子都已经处理完毕,树成功转化为二叉树。 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值