求一个节点在二叉树中的双亲结点

设计一个求节点在二叉树中的双亲结点算法。

/*
设计思路:以先序遍历二叉树的方法,从根结点出发,
         1、如果左子树等于x结点,则返回根结点,否则,递归查找左子树,直到找到x或者树为空。
         2、如果右子树等于x结点,则返回根结点,否则,递归查找右子树,直到找到x或者树为空。
*/
BiTNode *find_parents(BiTree T, BiTNode x) {
    if (T) {
        if (T->lchild && T->lchild->data == x.data) {
            return T;
        }
        if (T->rchild && T->rchild->data == x.data) {
            return T;
        }

        BiTNode *parents = NULL;
        return parents = find_parents(T->lchild, x) ? parents : find_parents(T->rchild, x);//递归查找左右子树
    }
    return nullptr;
}

改进版:

void in_order_find(BiTree T,BiTNode **parents, BiTNode x)
{
    if (T && (!*parents)) {
        if ( (T->lchild && T->lchild->data == x.data) || 
             (T->rchild && T->rchild->data == x.data) ) {
            *parents = T;
            return;
        }
        in_order_find(T->lchild, parents, x);
        in_order_find(T->rchild, parents, x);
    }
}

BiTNode *find_parents2(BiTree T, BiTNode x)
{
    BiTNode* parents = nullptr;
    in_order_find(T, &parents, x);
    return parents;
}

 

测试代码:

#include <stdio.h>
#include <stdlib.h>

typedef char TElemType;
typedef struct BiTNode
{
    TElemType data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

/*
设计思路:以先序遍历二叉树的方法,从根结点出发,
         1、如果左子树等于x结点,则返回根结点,否则,递归查找左子树,直到找到x或者树为空。
         2、如果右子树等于x结点,则返回根结点,否则,递归查找右子树,直到找到x或者树为空。
*/
BiTNode *find_parents(BiTree T, BiTNode x)
{
    if (T) {
        if (T->lchild && T->lchild->data == x.data) {
            return T;
        }
        if (T->rchild && T->rchild->data == x.data) {
            return T;
        }

        BiTNode *parents = NULL;
        return parents = find_parents(T->lchild, x) ? parents : find_parents(T->rchild, x);
    }
    return NULL;
}

/*
 *改进版
 *设计思路:以先序遍历二叉树的方法,从根结点出发,
         1、如果左子树等于x结点,则返回根结点,否则,递归查找左子树,直到找到x或者树为空。
         2、如果右子树等于x结点,则返回根结点,否则,递归查找右子树,直到找到x或者树为空。
 */
void in_order_find(BiTree T,BiTNode** parents, BiTNode x)
{
    if (T && (!*parents)) {
        if ( (T->lchild && T->lchild->data == x.data) || 
             (T->rchild && T->rchild->data == x.data) ) {
            *parents = T;
            return;
        }
        in_order_find(T->lchild, parents, x);
        in_order_find(T->rchild, parents, x);
    }
}

BiTNode *find_parents2(BiTree T, BiTNode x)
{
    BiTNode* parents = NULL;
    in_order_find(T, &parents, x);
    return parents;
}

/*
 * 查找兄弟节点
 */
BiTNode *find_brother(BiTree T, BiTNode x)
{
    BiTNode* parents = find_parents2(T, x);
    return parents ? 
           (parents->lchild && parents->lchild->data == x.data ? 
               parents->rchild : 
               parents->lchild) : 
           NULL;
}

//构造一棵测试二叉树
void CreatBiTree(BiTree *T)
{
    TElemType data;
    scanf("%c", &data);
    if (data == '#') {
        T = NULL;
    } else {
        *T = (BiTNode*)malloc(sizeof(BiTNode));
        if (!T)
            exit(-1);
        (*T)->data = data;
        CreatBiTree(&(*T)->lchild);
        CreatBiTree(&(*T)->rchild);
    }
}

int main(void)
{
    BiTree T = NULL;
    printf("根据输入二叉树的先序序列创建二叉树(空节点用“#”表示)\n");
    /*
     * 输入序列: abd#g##eh###c#fi##j##
     * 对应的二叉树: 
           a
         /   \
        b     c
      /   \    \
     d     e    f
      \   /    / \
       g h    i   j
    *
    */
    CreatBiTree(&T);
    printf("创建成功\n");

    BiTNode node;
    while(1) {
        printf("输入要查找的结点(输入‘#’退出)\n");
        scanf("\n%c", &node.data);/*使用scanf时注意,不同环境可能行为不一致*/
        if (node.data == '#')
            break;
        //BiTNode *parents = find_parents(T, node);
        BiTNode *parents = find_parents2(T, node);
        if (parents)
            printf("%c 的双亲结点是:%c\n",node.data, parents->data);
        else
            printf("没有找到双亲结点\n");
        BiTNode *brother = find_brother(T, node);
        if (brother)
            printf("%c 的双亲结点是:%c\n",node.data, brother->data);
        else
            printf("没有找到兄弟结点\n");
    }
    return 0;
}

 

作者:hellototoro

出处:求一个节点在二叉树中的双亲结点 - 行路难,多歧路 - 博客园 (cnblogs.com)
版权:本文版权归作者和博客园共有。
转载:欢迎转载,请保留此段。

posted @ 2021-11-17 16:05  行路难,多歧路  阅读(4788)  评论(7编辑  收藏  举报