树的括号表示

版权声明:转载请写明出处,谢谢! https://blog.csdn.net/wilson1068/article/details/88385988

树的括号表示

树的括号表示规则

  1. 若树 T 为空树,则其括号表示为空

  2. 若树 T 只包含一个结点,则其括号表示即为该结点本身

  3. 若树 T 由根结点 A 和它的 m 棵子树 T 1 , T 2 ,   , T m T_1, T_2, \cdots, T_m 构成,则其括号表示为:A ( T 1 T_1 的括号表示, T 2 T_2 的括号表示, \cdots , T m T_m 的括号表示)

其中,子树的括号表示同样应该遵循以上规则。

以下二叉树的括号表示结果为:

A(B(D(,H), E(I, J)), C(F, G(K)))

二叉树示例

括号表示法创建二叉树

注意:不保证输入参数的有效性,请自行确保。

每个节点的结构体为:

typedef struct _stBinaryTreeNode {
    void * data;                         // 保存数据,可以存储数据指针或者地址大小范围内的数值
    struct _stBinaryTreeNode * lchild;   // 左子节点的地址
    struct _stBinaryTreeNode * rchild;   // 右子节点的地址
} stBinaryTreeNode;

括号表示法以“最小”的括号包含一个最小的树,所以建立树的时候需要采用类似深度优先搜索的方式,建立最底层的树,然后往上完善一棵棵树。

通过括号表达式,建立二叉树的方法为:

stBinaryTreeNode * createBinaryTree(char * strBrackTree) {
    stBinaryTreeNode * root = NULL;
    if (strBrackTree == NULL) {
        return root;
    }

    int len = strlen(strBrackTree);
    if (len == 0) {
        return root;
    }
    
    // 栈,保存 node 节点地址
    stBinaryTreeNode ** node_stack = (stBinaryTreeNode **) malloc(sizeof(stBinaryTreeNode *) * len);
    int top = -1;
    stBinaryTreeNode * node;
    int child_index = 0;
    for (int i = 0; i < len; ++ i) {
        char ch = strBrackTree[i];
        switch (ch) {
            case '(':
                node_stack[++top] = node;       // 保存当前 parent 节点
                child_index = 0;                // 初始化子节点 index
                break;
            case ',':
                child_index ++;                 // 更新子节点 index
                break;
            case ')':
                node_stack[--top];              // 移除已匹配的 parent 节点
                break;
            case ' ':
                break;
            default:
                node = (stBinaryTreeNode *) malloc(sizeof(stBinaryTreeNode));
                node->lchild = NULL;
                node->rchild = NULL;
                node->data = (void *) ch;
                if (root == NULL) {
                    root = node;
                } else {
                    if (child_index == 0) {
                        node_stack[top]->lchild = node;    // 更新当前 parent 的左子节点
                    } else {
                        node_stack[top]->rchild = node;    // 更新当前 parent 的右子节点
                    }
                }
                break;
        }
    }
    free(node_stack);
    return root;
}

递归式打印出该树的括号表达式的方法:

int printBinaryTreeToBrackString(stBinaryTreeNode * node, char * out_msg) {
    int out_len = 0;
    if (out_msg == NULL || node == NULL) {
        return out_len;
    }

    out_msg[out_len++] = (int) node->data;
    if (node->lchild != NULL || node->rchild != NULL) {
        out_msg[out_len++] = '(';
        out_len += printBinaryTreeToBrackString(node->lchild, out_msg + out_len);
        if (node->rchild != NULL) {
            out_msg[out_len++] = ',';
        }
        out_len += printBinaryTreeToBrackString(node->rchild, out_msg + out_len);
        out_msg[out_len++] = ')';
    }
    out_msg[out_len] = 0;

    return out_len;
}

测试数据运行结果如下:

INPUT  TREE : A(B(D(,H), E(I, J)), C(F, G(K)))
OUTPUT TREE : A(B(D(,H),E(I,J)),C(F,G(K))) ### len = 28

完整代码如下:

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

#define BRACK_TO_BINARY_TREE    "A(B(D(, H), E(I, J)), C(F, G(K)))"

typedef struct _stBinaryTreeNode {
    void * data;                         // 保存数据,可以存储数据指针或者地址大小范围内的数值
    struct _stBinaryTreeNode * lchild;   // 左子节点的地址
    struct _stBinaryTreeNode * rchild;   // 右子节点的地址
} stBinaryTreeNode;

stBinaryTreeNode * createBinaryTree(char * strBrackTree) {
    stBinaryTreeNode * root = NULL;
    if (strBrackTree == NULL) {
        return root;
    }

    int len = strlen(strBrackTree);
    if (len == 0) {
        return root;
    }
    
    // 栈,保存 node 节点地址
    stBinaryTreeNode ** node_stack = (stBinaryTreeNode **) malloc(sizeof(stBinaryTreeNode *) * len);
    int top = -1;
    stBinaryTreeNode * node;
    int child_index = 0;
    for (int i = 0; i < len; ++ i) {
        char ch = strBrackTree[i];
        switch (ch) {
            case '(':
                node_stack[++top] = node;       // 保存当前 parent 节点
                child_index = 0;                // 初始化子节点 index
                break;
            case ',':
                child_index ++;                 // 更新子节点 index
                break;
            case ')':
                node_stack[--top];              // 移除已匹配的 parent 节点
                break;
            case ' ':
                break;
            default:
                node = (stBinaryTreeNode *) malloc(sizeof(stBinaryTreeNode));
                node->lchild = NULL;
                node->rchild = NULL;
                node->data = (void *) ch;
                if (root == NULL) {
                    root = node;
                } else {
                    if (child_index == 0) {
                        node_stack[top]->lchild = node;    // 更新当前 parent 的左子节点
                    } else {
                        node_stack[top]->rchild = node;    // 更新当前 parent 的右子节点
                    }
                }
                break;
        }
    }
    free(node_stack);
    return root;
}

int printBinaryTreeToBrackString(stBinaryTreeNode * node, char * out_msg) {
    int out_len = 0;
    if (out_msg == NULL || node == NULL) {
        return out_len;
    }

    out_msg[out_len++] = (int) node->data;
    if (node->lchild != NULL || node->rchild != NULL) {
        out_msg[out_len++] = '(';
        out_len += printBinaryTreeToBrackString(node->lchild, out_msg + out_len);
        if (node->rchild != NULL) {
            out_msg[out_len++] = ',';
        }
        out_len += printBinaryTreeToBrackString(node->rchild, out_msg + out_len);
        out_msg[out_len++] = ')';
    }
    out_msg[out_len] = 0;

    return out_len;
}

stBinaryTreeNode * destoryBinaryTree(stBinaryTreeNode * node) {
    if (node != NULL) {
        destoryBinaryTree(node->lchild);
        destoryBinaryTree(node->rchild);
        free(node);
        node = NULL;
    }
    return node;
}

int main() {
    char msg[128];
    stBinaryTreeNode * tree = createBinaryTree(BRACK_TO_BINARY_TREE);
    printf("INPUT  TREE : %s\n", BRACK_TO_BINARY_TREE);
    int len = printBinaryTreeToBrackString(tree, msg);
    printf("OUTPUT TREE : %s ### len = %d\n", msg, len);
    tree = destoryBinaryTree(tree);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wilson1068/article/details/88385988