当前位置:首页数据结构 > 正文

什么是树的孩子表示法?

作者:野牛程序员:2023-05-11 14:37:52数据结构阅读 2820

树的孩子表示法(Child-Sibling Representation),也称为左孩子右兄弟表示法(Left-Child Right-Sibling Representation),是一种用于表示树结构的常见方法。在这种表示法中,每个节点包含两个指针,分别指向其第一个孩子节点和其兄弟节点。这样的表示方法适合描述不同的树结构,如二叉树和多叉树等。

具体地,对于一个节点而言,其第一个孩子节点可以通过其左指针找到,而其兄弟节点可以通过其右指针找到。如果一个节点没有孩子节点,那么其左指针指向空,如果一个节点没有兄弟节点,那么其右指针指向空。

树的孩子表示法可以有效地描述树的结构,尤其是在需要进行树的遍历和搜索等操作时,具有一定的优势。

#include <iostream>
#include <vector>

using namespace std;

// 树节点的结构体定义
struct TreeNode {
    int val;
    TreeNode* firstChild;   // 指向第一个孩子节点
    TreeNode* nextSibling;  // 指向兄弟节点
    TreeNode(int x) : val(x), firstChild(NULL), nextSibling(NULL) {}
};

// 建立一棵树
TreeNode* buildTree() {
    int n, val;
    cout << "请输入节点个数: ";
    cin >> n;
    vector<TreeNode*> nodes(n); // 存放每个节点的指针
    cout << "请依次输入每个节点的值: ";
    for (int i = 0; i < n; i++) {
        cin >> val;
        nodes[i] = new TreeNode(val);
    }
    int rootIndex, parentIndex, childIndex;
    cout << "请依次输入每个节点的父节点编号(根节点编号为 0): ";
    for (int i = 1; i < n; i++) {
        cin >> parentIndex;
        childIndex = i;
        // 将当前节点作为其父节点的孩子节点或兄弟节点
        if (nodes[parentIndex]->firstChild == NULL) {
            nodes[parentIndex]->firstChild = nodes[childIndex];
        } else {
            TreeNode* sibling = nodes[parentIndex]->firstChild;
            while (sibling->nextSibling != NULL) {
                sibling = sibling->nextSibling;
            }
            sibling->nextSibling = nodes[childIndex];
        }
    }
    return nodes[0]; // 返回根节点指针
}

// 先序遍历输出树
void preorderTraversal(TreeNode* root) {
    if (root == NULL) {
        return;
    }
    cout << root->val << " ";
    preorderTraversal(root->firstChild);
    preorderTraversal(root->nextSibling);
}

int main() {
    TreeNode* root = buildTree();
    cout << "先序遍历输出树的节点值: ";
    preorderTraversal(root);
    return 0;
}


在上面的示例中,我们首先定义了一个树节点的结构体,其中包含了节点的值 val、指向第一个孩子节点的指针 firstChild 和指向兄弟节点的指针 nextSibling

接下来,我们定义了一个 buildTree() 函数,用于通过输入建立一棵树。在该函数中,我们首先输入节点个数和每个节点的值,并存放到一个 vector 中。然后,我们逐个输入每个节点的父节点编号,并将当前节点作为其父节点的孩子节点或兄弟节点。最后,我们返回根节点的指针。

最后,我们定义了一个 preorderTraversal() 函数,用于先序遍历输出树的节点值。在该函数中,我们首先输出当前节点的值,然后递归遍历其第一个孩子节点和兄弟节点。


代码2:

#include <iostream>

using namespace std;

// 树节点的结构体定义
struct TreeNode {
    int val;
    TreeNode* firstChild;   // 指向第一个孩子节点
    TreeNode* nextSibling;  // 指向兄弟节点
    TreeNode(int x) : val(x), firstChild(NULL), nextSibling(NULL) {}
};

// 树节点的个数
const int MAX_N = 100;

// 存放每个节点的指针
TreeNode* nodes[MAX_N];

// 当前节点编号
int nodeIndex = 0;

// 建立一棵树
TreeNode* buildTree() {
    int n, val, parentIndex, childIndex;
    cout << "请输入节点个数: ";
    cin >> n;
    cout << "请依次输入每个节点的值: ";
    for (int i = 0; i < n; i++) {
        cin >> val;
        nodes[i] = new TreeNode(val);
    }
    cout << "请依次输入每个节点的父节点编号(根节点编号为 0): ";
    for (int i = 1; i < n; i++) {
        cin >> parentIndex;
        childIndex = i;
        // 将当前节点作为其父节点的孩子节点或兄弟节点
        if (nodes[parentIndex]->firstChild == NULL) {
            nodes[parentIndex]->firstChild = nodes[childIndex];
        } else {
            TreeNode* sibling = nodes[parentIndex]->firstChild;
            while (sibling->nextSibling != NULL) {
                sibling = sibling->nextSibling;
            }
            sibling->nextSibling = nodes[childIndex];
        }
    }
    return nodes[0]; // 返回根节点指针
}

// 先序遍历输出树
void preorderTraversal(TreeNode* root) {
    if (root == NULL) {
        return;
    }
    cout << root->val << " ";
    preorderTraversal(root->firstChild);
    preorderTraversal(root->nextSibling);
}

int main() {
    TreeNode* root = buildTree();
    cout << "先序遍历输出树的节点值: ";
    preorderTraversal(root);
    return 0;
}

在这个示例代码中,我们使用一个 nodes 数组来存放每个节点的指针,其大小为常量 MAX_N。在建立树时,我们先输入节点个数和每个节点的值,并将其存放到 nodes 数组中。然后,我们逐个输入每个节点的父节点编号,并将当前节点作为其父节点的孩子节点或兄弟节点。最后,我们返回根节点的指针。

preorderTraversal() 函数中,我们同样使用了递归的方式进行先序遍历,并输出当前节点的值、其第一个孩子节点和兄弟节点的值。


野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892
野牛程序员教少儿编程与信息学竞赛-微信|电话:15892516892
相关推荐

最新推荐

热门点击