数据结构 ——二叉树转广义表

news/2024/12/15 20:42:35/

数据结构 ——二叉树转广义表

1、树转广义表
如下一棵树,转换为广义表
在这里插入图片描述
root=(c(a()(b()()))(e(d()())(f()(j(h()())())))) (根(左子树)(右子树))

  • 代码实现
#include<stdio.h>
#include<stdlib.h>//保存二叉树到文件
#define FNAME "../test16_save/out.txt"
#define NAMESIZE 32
struct node_st
{char data;struct node_st *l,*r;
};
struct node_st *tree=NULL;
//char型会存在不可预知的字符,不用它来传参
int insert(struct node_st **root,int data)
{struct node_st *node;//走到空节点或叶子节点if(*root==NULL){node=(struct node_st*)malloc(sizeof(struct node_st));if(node==NULL)return -1;node->data=data;node->l=NULL;//防止野指针的出现node->r=NULL;*root=node;//根节点指向创建出来的新节点,后面递归时root为传入的左或右子树的指针return 0; }//比当前节点小的插入左子树,比节点大的插入右子树,递归遍历if(data<=(*root)->data)return insert(&(*root)->l,data);return insert(&(*root)->r,data);
}
void draw_(struct node_st *root,int level)
{/*往左边倒,画出树的结构,先画当前节点的右子树,再跟节点,最后root->rrootroot->l*/if(root==NULL)return; //空节点或空的叶子结点//先画右子树,右子树不止一层,所以递归调用,画右子树的右子树(当前层的下一层)draw_(root->r,level+1);//画空格,即当前节点前面的空格for(int i=0;i<level;i++)printf("  ");//画根节点printf("%c\n",root->data);//画左子树draw_(root->l,level+1);}
void draw(struct node_st *root)
{//根据层数画出树和空格draw_(root,0);
}
//销毁二叉树,后序遍历思想:先销毁当前节点的左子树,再销毁当前节点的右子树,最后销毁当前节点
void destroy(struct node_st *root)
{if(root==NULL)return ;destroy(root->l);destroy(root->r);free(root);
}
//保存为广义表的形式,(根(左子树)(右子树))
int save_(struct node_st *root,FILE *fp)
{fputc('(',fp);//为空,或走到叶子结点if(root ==NULL){fputc(')',fp);return 0;}//不为空,把根节点打印出来fputc(root->data,fp);//递归保存左子树save_(root->l,fp);//递归保存右子树save_(root->r,fp);fputc(')',fp);return 0;
}
int save(struct node_st *root,const char *path)
{FILE *fp=fopen(path,"w");if(fp==NULL){printf("open file %s failed\n",path);return -1;}// save_(root,fp);save_(tree,fp);fclose(fp);return 0;
}
int main()
{char arr[]="cefadjbh";int i;for(i=0;i<sizeof(arr)/sizeof(arr[0])-1;i++) //-1是为了去掉最后一个'\0'{//无头节点要改变指针的指向,传二级指针insert(&tree,arr[i]);}draw(tree);save(tree,FNAME);destroy(tree);return 0;
}

2、根据广义表画出二叉树
假设广义表为 (c(a()(b()()))(e(d()())(f()(j(h()())())))) 画出该二叉树
实现过程:先拿到表的第一个字符,判断是不是(,是的话继续拿第二个字符,不是)的话,则为根节点,保存该根节点数据;继续左右子树的递归存值,读完左右子树后,继续读最后一个),递归结束,返回这棵树。

  • 代码实现
#include<stdio.h>
#include<stdlib.h>#define FNAME "../test16_save/out.txt"
#define NAMESIZE 32
struct node_st
{char data;struct node_st *l,*r;
};
void draw_(struct node_st *root,int level)
{/*往左边倒,画出树的结构,先画当前节点的右子树,再跟节点,最后root->rrootroot->l*/if(root==NULL){//   printf("Empty node at level %d\n", level);  // Debug outputreturn;}//先画右子树,右子树不止一层,所以递归调用,画右子树的右子树(当前层的下一层)draw_(root->r,level+1);//画空格,即当前节点前面的空格for(int i=0;i<level;i++)printf("  ");//画根节点printf("%c\n",root->data);//画左子树draw_(root->l,level+1);}
void draw(struct node_st *root)
{//根据层数画出树和空格printf("draw tree:\n");draw_(root,0);
}
struct node_st *load_(FILE *fp)
{int c;struct node_st *root;c=fgetc(fp);//读到的第一个一定是(,不是说明文件有问题if(c!='('){fprintf(stderr,"fgetc():error\n");exit(1);}c=fgetc(fp);//读完( 后,继续读到),说明树为空if(c==')')return NULL;//读到根节点,保存到root中root=malloc(sizeof(*root));if(root==NULL){fprintf(stderr,"malloc():error\n");exit(1);}root->data=c;//继续读左右子树root->l=load_(fp);root->r=load_(fp);//读完左右子树后,继续读最后一个)c=fgetc(fp);if(c!=')'){fprintf(stderr,"fgetc():error\n");return NULL;}return root;  
}
struct node_st *load(const char *path)
{FILE *fp;fp=fopen(path,"r");struct node_st *root;if(fp==NULL){printf("open file %s failed\n",path);return NULL;}root=load_(fp);fclose(fp);return root;
}int main()
{struct node_st *root;root=load(FNAME);draw(root);return 0;
}

http://www.ppmy.cn/news/1555401.html

相关文章

Scala记号字面值 空白与注释

记号字面值 语法&#xff1a; symbolLiteral :: „‟‟ idrest 记号字面值‟x 是表达式 scala.Symbol(“x”)的简写形式。Symbol 是一个 case 类(5.3.2)&#xff0c;定义如下&#xff1a; package scala final case class Symbol private (name: String) { override def toStri…

每天40分玩转Django:Django模型

Django框架学习第2天&#xff1a;Django模型 一、课程概述 学习项目具体内容预计用时模型定义模型类编写、字段类型、关系类型90分钟ORM操作增删改查、高级查询、聚合函数90分钟数据库迁移迁移命令、迁移文件、数据导入导出60分钟 二、模型定义 2.1 基本模型结构 # blog/mo…

【数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;编写一个程序实现单链表的基本运算。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;初始化线性表、销毁线性表、判定是否为空表、求线性…

使用idea创建一个JAVA WEB项目

文章目录 1. javaweb项目简介2. 创建2.1 idea新建项目2.2 选择&#xff0c;命名2.3 打开2.4 选择tomcat运行2.5 结果 3. 总结 1. javaweb项目简介 JavaWeb项目是一种基于Java技术的Web应用程序&#xff0c;主要用于开发动态网页和Web服务。这种项目能够构建在Java技术栈之上&a…

使用 UniApp 实现简单的个人中心页面

1. 创建 UniApp 项目 首先&#xff0c;确保你已经安装了 HBuilderX 或其他支持 UniApp 的开发工具。然后创建一个新的 UniApp 项目。 # 使用 HBuilderX 创建新项目 # 选择 uni-app 模板 -> 选择 Vue.js 模板 -> 输入项目名称 -> 创建2. 安装依赖 UniApp 内置了一些…

交流负载箱的安全事项和注意事项有哪些?

交流负载箱用于模拟实际负载的电气设备&#xff0c;广泛应用于电力系统、通信系统、自动化控制系统等领域。在使用过程中&#xff0c;为确保人身和设备安全&#xff0c;需要注意以下安全事项和注意事项&#xff1a; 选择合适的交流负载箱&#xff1a;根据实际需求选择合适的交…

Python生成对抗神经网络GAN预测股票及LSTMs、ARIMA对比分析ETF金融时间序列可视化

全文链接&#xff1a;https://tecdat.cn/?p38528 本文聚焦于利用生成对抗网络&#xff08;GANs&#xff09;进行金融时间序列的概率预测。介绍了一种新颖的基于经济学驱动的生成器损失函数&#xff0c;使 GANs 更适用于分类任务并置于监督学习环境中&#xff0c;能给出价格回…

CodeFuse「编码挑战季」:冲刺最后1个月!MelGeek磁轴键盘、Beats耳机等你来拿~

本次活动自 1024 程序员节开始&#xff0c;12 月底结束&#xff0c;还有一个月的挑战时间&#xff0c;速来参与&#xff0c;赢取超值奖品&#xff01;&#xff01;&#xff01; 活动介绍 本次 CodeFuse「编码挑战季」活动&#xff0c;需实际完成muAgent、MFTCoder、ModelCache…