C语言创建销毁儿子兄弟链树以凹入表示法输出树查看儿子兄弟链树高度

Posted Z.Q.Feng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言创建销毁儿子兄弟链树以凹入表示法输出树查看儿子兄弟链树高度相关的知识,希望对你有一定的参考价值。


前言

网上大多数的创建孩子兄弟链树的生成算法都只限于含有两个兄弟结点的创建,对于三个兄弟结点的情况没有给出相应的处理,在使用过程中我改进了算法中的一些部分,可供参考。

此外,我还提供了为该树的各叶子结点赋值求叶子结点总数插入结点求某结点下叶子数目等算法,详情参考我的另一篇博客:

顺带吐槽:孩子是禁止词儿子不是。。。CSDN这审核。。。


数据结构

#include <iostream>
using namespace std;

#define MaxSize 50

//char str[MaxSize] = "A(B(C(D,E)),F(G))";
//char str[MaxSize] = "A(B(D(G)),C(E,F))";
char str[MaxSize] = "A(B(C(D,E),L(M,N)),G,H(I,J(K)))";

//孩子兄弟链式存储结构
typedef struct tnode
    char name;
    int data; //叶子结点包含数据
    struct tnode *hp; //指向兄弟
    struct tnode *vp; //指向孩子结点
TSBNode;

创建孩子兄弟链树

/*
孩子兄弟链树创建算法:(兄弟结点3个内可行)
    A-Z: 为根结点或根据k值判断是栈顶元素的孩子或兄弟结点
    左括号: p进栈,k=1,置flag=true
    右括号: 置flag1=true,成功匹配左括号(flag=true)退栈count2次,利用count1记录匹配次数
            第一次不匹配左括号退栈count1次,后述退栈2次,置count1=0
    逗号: 若前为右括号,置k=2,count2=0,否则p进栈,置k=2,利用count2记录逗号出现次数
*/
void CreateTree(TSBNode* &bt, char *str)
    TSBNode *St[MaxSize], *p;
    int top = -1, k, j = 0, count1 = 0, count2 = 0;
    char ch;
    bt = NULL;
    ch = str[j];
    bool flag = true, flag1 = false, flag2 = true;
    while(ch != '\\0')
        switch(ch)
            case '(': //左括号
                top++; St[top] = p; k = 1;
                flag = true; break; //flag用于匹配右括号
            case ')': //右括号
                if (flag) //成功匹配左括号
                    top -= count2; count1++; flag = false;
                    flag1 = true; flag2 = true; break; //count1记录成功匹配次数
                
                else
                    if (flag2) //flag2用于判断是否第一次不匹配右括号
                        top -= count1; count1 = 0;
                        flag1 = true; flag2 = false; break;
                    
                    else //第二次不匹配右括号
                        flag1 = true; top -= 2; break;
                    
                
            case ',': //逗号
                if (flag1) //flag1判断前是否为右括号
                    k = 2; count2 = 0; break;
                
                else //逗号前不为右括号
                    k = 2; top++; St[top] = p;
                    count2 += 1; break; //count2记录逗号出现次数
                
            default: //A-Z
                flag1 = false; //非右括号元素会使flag1值为false
                p = (TSBNode*)malloc(sizeof(TSBNode));
                p->name = ch; p->data = -1;
                p->hp = p->vp = NULL;
                if (bt == NULL)
                    bt = p; //链为空增添根结点
                else
                    switch (k)
                        case 1: //k为1为栈顶元素的孩子结点
                            St[top]->vp = p; break;
                        case 2: //k为2为栈顶元素的兄弟结点
                            St[top]->hp = p; break;
                    
                
                break;
        
        ch = str[++j];
    


销毁孩子兄弟链树

void DestoryTree(TSBNode *&bt)
    if (bt)
        if (bt->hp)
            DestoryTree(bt->hp);
        else if (bt->vp)
            DestoryTree(bt->vp);
        free(bt);
    


以凹入表示法输出树

//以凹入表示法输出树
void ShowTree(TSBNode *bt, int layer)
    int i = 0;
    if (bt)
        for (i; i < layer; i++)
            cout << "    ";
        cout << bt->name;
        if (bt->data != -1)
            cout << "(" << bt->data << ")";
        cout << endl;
        ShowTree(bt->vp, layer + 1);
        ShowTree(bt->hp, layer);
    


求树的高度

//查看这棵树的高度
int TreeHeight(TSBNode *bt)
    TSBNode *p;
    int h, maxh = 0;
    if (bt == NULL)
        return 0;
    else
        p = bt->vp;
        while (p != NULL)
            h = TreeHeight(p);
            if (maxh < h)
                maxh = h;
            p = p->hp;
        
    
    return (maxh + 1);


运行示例

对于这样一棵树:


其广义表表示如下:

char str[MaxSize] = "A(B(C(D,E),L(M,N)),G,H(I,J(K)))";

创建并使用凹入表示法输入如下:

以上是关于C语言创建销毁儿子兄弟链树以凹入表示法输出树查看儿子兄弟链树高度的主要内容,如果未能解决你的问题,请参考以下文章

二叉树输出(btout)

树的孩子兄弟表示法实例(C++实现的)

左子右兄弟表达式树

如何创建 LINQ 表达式树以选择匿名类型

树/森林和二叉树的转换

UVa 11732 "strcmp()" Anyone? (左儿子右兄弟前缀树Trie)