免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4168 | 回复: 13
打印 上一主题 下一主题

[C] 二叉树,文本双向转换 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-03-31 16:14 |只看该作者 |倒序浏览
10可用积分
现在在做一个多分类程序,需要保存二叉树
要求将内存中的二叉树保存成文本形式,文本具有可读性,可编辑性。并且从文本恢复的二叉树与原二叉树相同

目前我想到的方式是保存父子关系,比如:
ABC
BED
CFG
EHI
...

哪位高人给个更好的方案阿

最佳答案

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2008-03-31 16:14 |只看该作者
A(B(C,D),E)

论坛徽章:
0
3 [报告]
发表于 2008-03-31 17:00 |只看该作者
我觉得你那个方案就蛮好了,第一个元素是root,第二个是左子树,第三个是右子树

论坛徽章:
0
4 [报告]
发表于 2008-03-31 17:02 |只看该作者
这个好, 程序简单, 和树结构一致.

缺点是不容易看懂.

原帖由 cjaizss 于 2008-3-31 16:16 发表
A(B(C,D),E)

论坛徽章:
0
5 [报告]
发表于 2008-03-31 17:07 |只看该作者
或者你可以考虑再多一个域保存父节点的,这样一个节点保存的信息就很完备了.

论坛徽章:
0
6 [报告]
发表于 2008-03-31 19:48 |只看该作者
原帖由 cjaizss 于 2008-3-31 16:16 发表
A(B(C,D),E)

这种表达怎么从文本恢复二叉树呢,是不是要写个解析表达式的代码,具体说清楚下,谢谢

论坛徽章:
0
7 [报告]
发表于 2008-03-31 21:09 |只看该作者
解决了,使用中序遍历,加栈方式来解决
A(B(C,D),E)实质上是对树的中序遍历,恢复的时候算法如下

take A, make node A
take ( , push A into stack
take B, make node B,left child of A
take ( , push B into stack
take C, make node C,left child of B
take , , nothing
take D, make node D,right child of B
take ) , pop D from stack
take , , nothing
take E, make node E,right child of A
take ) , pop A from stack

论坛徽章:
0
8 [报告]
发表于 2008-04-01 14:45 |只看该作者
贴下实现代码,很简洁,缺点是有点不稳定

typedef struct _node{
    char name[10];
    char tempfile0[10];
    char tempfile1[10];
    uint8_t temp0[stdWidth*stdHeight];
    uint8_t temp1[stdWidth*stdHeight];
    struct _node *child0;
    struct _node *child1;
} Node;

int readTree(char *filename,Node *tree,int32_t treesize)
{
    FILE * f;
    char lastToken = -1;
    char CurrToken = -1;
    int32_t CurrTokenLen;
    int32_t pn = 0;
    int32_t stack[30];
    int32_t *stacktop = stack-1;
    char whitechar[3]=" \n\t";

    memset(tree,0,treesize*sizeof(Node));

    f = fopen (filename,"r");

    while (!feof(f)){
        if (!fscanf(f,"%c",&CurrToken)) goto die;
        switch (CurrToken){
        case ':':
            fscanf(f,"%s",(tree[pn].name));
            fscanf(f,"%s",(tree[pn].tempfile0));
            fscanf(f,"%s",(tree[pn].tempfile1));

            if (lastToken == '(')
                tree[*stacktop].child0 = tree + pn;
            if (lastToken == ',')
                tree[*stacktop].child1 = tree + pn;
            break;
        case '(':
            *(++stacktop) = pn;
            pn++;
            break;
        case ')':
            stacktop --;
            break;
        case ',':
            pn++;
            break;
        case ' ':
            break;
        default:
            break;
        }

        if (CurrToken == ',' || CurrToken == '(' || CurrToken == ')')
            lastToken = CurrToken;
    }
die:
    fclose(f);
    return 0;
}

int
codeTree(FILE *f,Node *tree)
{
    int retval = 0;
    printf(" : %s %s %s ",tree->name,tree->tempfile0,tree->tempfile1);
    if (tree->child0 && tree->child1)
    {
        printf("\n (");
        retval = codeTree(f,tree->child0);
        printf(" , ");
        retval += codeTree(f,tree->child1);
        printf(" ) \n");
        return retval;
    }
    return 1;
}
能够解析下述文本
: a a a ( : b b b ( : d d d , : e e e ) , : c c c )

程序中序遍历的输出是
: a a a  ( : b b b  ( : d d d  ,  : e e e  )  ,  : c c c  )


目前文本格式还很难看,正在想办法美化成如下形式
(a a a) {(b b b) {(c c c) , (d d d)},(e e e)}


[ 本帖最后由 reiase 于 2008-4-1 15:01 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2008-04-01 14:55 |只看该作者
LZ,你用递归,而不是循环来实现,可能看起来会好些,如果对性能要求不是很高的话.

论坛徽章:
0
10 [报告]
发表于 2008-04-01 15:00 |只看该作者
原帖由 converse 于 2008-4-1 14:55 发表
LZ,你用递归,而不是循环来实现,可能看起来会好些,如果对性能要求不是很高的话.


感谢LS的意见,请说清楚点,我不太清楚你指得是哪里
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP