[Data Structure] Trees and Binary Trees (Twenty-five): Tree search for the father of a given node (algorithm FindFather)

Article directory

  • 5.3.1 Tree storage structure
    • 5. Left son and right brother link structure
  • 5.3.2 Algorithm for obtaining nodes
    • 1. Obtain the eldest son and eldest brother nodes
    • 2. Search for the parent of a given node
      • a. Algorithm FindFather
      • b. Algorithm analysis
      • c. Code implementation
    • 3. Code integration

5.3.1 Tree storage structure

5. Left son and right brother link structure

[Data Structure] Trees and Binary Trees (19): Storage structure of the tree - left son, right brother link structure (transformation of tree, forest and binary tree)
  Left son, right The sibling link structure builds a tree by using three fields of each node (FirstChild, Data, NextBrother), while making the tree have the properties of a binary tree. Specifically, each node contains the following information:

  1. FirstChild: Stores a pointer to the eldest son (leftmost child node) of this node. This pointer allows us to quickly find the first child node of a node.
  2. Data: stores node data.
  3. NextBrother: Stores a pointer to the node's eldest brother (the right sibling node in the same layer). This pointer allows us to quickly find the next sibling node of a node in the same layer.

  Through this structure, the entire tree can be represented as a binary tree using the left son and right sibling link structure. This representation is sometimes used in some special tree structures, such as binary trees, binary tree forests, etc. One of the advantages of this structure is that it represents the tree more compactly without requiring extra pointers to represent sibling relationships.
Insert image description here

   A
  /|\
 B C D
  / \
 E   F
A
|
B -- C -- D
     |
     E -- F

Right now:

      A
     / 
    B   
    \
	  C
  	 / \ 
  	E   D
  	 \
  	  F

Insert image description here

5.3.2 Algorithm for obtaining nodes

1. Obtain the eldest son and eldest brother nodes

[Data Structure] Trees and Binary Trees (20): Algorithms for trees to obtain the eldest son and eldest brother nodes (GFC, GNB)

2. Search for the parent of a given node

  • recursive thinking
    • The given node means that the given node is a pointer to a certain node (such as p).
    • The return value should also be a pointer, pointing to the parent of node p (null if not found).

a. Algorithm FindFather

Insert image description here

b. Algorithm analysis

  Algorithm FindFather searches for the parent node of the node pointed to by pointer p in the tree with t as the root pointer, similar to root-first traversal, and its time complexity is O(n).

  1. First, set the result pointer to null.
  2. If t is empty or p is empty, or p is equal to t, then return directly.
  3. Point the pointer q to the first child node of t.
  4. Enter a loop as long as q is not empty:
    • If q equals p, it means that the parent node of p is found, the result pointer points to t, and then returns.
    • Otherwise, call the FindFather function recursively, passing in the parameters q and p, and store the result in result.
    • If result is not empty, it means that the parent node has been found and returns directly.
    • Update pointer q to the next sibling node of q.
  5. If the parent node is still not found at the end of the loop, the result is still empty.

c. Code implementation

void FindFather(TreeNode* t, TreeNode* p, TreeNode** result) {
    
    
    *result = NULL;

    if (t == NULL || p == NULL || p == t) {
    
    
        return;
    }

    TreeNode* q = t->firstChild;

    while (q != NULL) {
    
    
        if (q == p) {
    
    
            *result = t;
            return;
        }

        FindFather(q, p, result);

        if (*result != NULL) {
    
    
            return;
        }

        q = q->nextBrother;
    }
}

  Overview of the recursive process:

  • If the tree is empty or the given node is empty or the given node is the root node, NULL is returned by definition.
  • qPoint to the left child node of the root node and enter the loop
    • If the given node is the left son of the root node, then the root node is its parent.
    • In the left subtreeRecursive search
      • …………
    • If the parent node is found, return directly
    • is not found, thenq is updated to the right brother of the left son (i.e. the next child node)
      • Continue the recursive search...

3. Code integration

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

// 定义树节点
typedef struct TreeNode {
    
    
    char data;
    struct TreeNode* firstChild;
    struct TreeNode* nextBrother;
} TreeNode;

// 创建树节点
TreeNode* createNode(char data) {
    
    
    TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
    if (newNode != NULL) {
    
    
        newNode->data = data;
        newNode->firstChild = NULL;
        newNode->nextBrother = NULL;
    }
    return newNode;
}

// 释放树节点及其子树
void freeTree(TreeNode* root) {
    
    
    if (root != NULL) {
    
    
        freeTree(root->firstChild);
        freeTree(root->nextBrother);
        free(root);
    }
}


// 算法 FindFather
void FindFather(TreeNode* t, TreeNode* p, TreeNode** result) {
    
    
    *result = NULL;

    if (t == NULL || p == NULL || p == t) {
    
    
        return;
    }

    TreeNode* q = t->firstChild;

    while (q != NULL) {
    
    
        if (q == p) {
    
    
            *result = t;
            return;
        }

        FindFather(q, p, result);

        if (*result != NULL) {
    
    
            return;
        }

        q = q->nextBrother;
    }
}


int main() {
    
    
    // 构建左儿子右兄弟链接结构的树
    TreeNode* A = createNode('A');
    TreeNode* B = createNode('B');
    TreeNode* C = createNode('C');
    TreeNode* D = createNode('D');
    TreeNode* E = createNode('E');
    TreeNode* F = createNode('F');

    A->firstChild = B;
    B->nextBrother = C;
    C->nextBrother = D;
    C->firstChild = E;
    E->nextBrother = F;

    // // 层次遍历算法
    // printf("Level Order: \n");
    // LevelOrder(A);
    // printf("\n");
    // 要查找父亲的节点
    TreeNode* targetNode = E;
    TreeNode* result = NULL;

    // 使用算法 FindFather 查找父亲
    FindFather(A, targetNode, &result);

    // 输出结果
    if (result != NULL) {
    
    
        printf("The father of %c is %c\n", targetNode->data, result->data);
    } else {
    
    
        printf("Node not found or it is the root.\n");
    }

    // 释放树节点
    freeTree(A);

    return 0;
}

Insert image description here

Guess you like

Origin blog.csdn.net/m0_63834988/article/details/134678334