求一個節點在二叉樹中的雙親結點


設計一個求節點在二叉樹中的雙親結點算法。

/*
設計思路:以先序遍歷二叉樹的方法,從根結點出發,
         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)
版權:本文版權歸作者和博客園共有。
轉載:歡迎轉載,請保留此段。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM