数据结构 ——树状存储的实现

news/2024/12/13 12:32:07/

数据结构 ——树状存储的实现

1、树的遍历
按层遍历:从树的根节点开始,逐层遍历树中的所有节点。这种遍历方式也称为广度优先遍历。

先序遍历(前序遍历):先访问根节点,然后递归地先序遍历左子树,最后递归地先序遍历右子树。

中序遍历:先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。

后序遍历:先递归地后序遍历左子树,然后递归地后序遍历右子树,最后访问根节点。

先序和中序 /中序和后序 能确定一颗树

下面为各种遍历示意图
在这里插入图片描述
2、代码实现
下面是以递归的思想来构建和遍历一颗二叉树

#include<stdio.h>
#include<stdlib.h>
#define NAMESIZE 32
//以无头节点的链表构建二叉树
struct score_st
{int id;char name[NAMESIZE];int math;int chinese;
};
struct node_st
{struct score_st data;struct node_st *l,*r;
};
void print_s1(struct score_st *d)
{printf("%d %s %d %d\n",d->id,d->name,d->math,d->chinese);
}
//插入原则:比当前节点小的插入左子树,比节点大的插入右子树 
int insert(struct node_st **root,struct score_st *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->id<=(*root)->data.id)return insert(&(*root)->l,data);return insert(&(*root)->r,data);
}
struct score_st *find(struct node_st *root,int id)
{//传过来的节点为叶子节点空的左或右孩子,说明走到了一个不存在的分支if(root==NULL)return NULL;if(id==root->data.id)return &(root->data);//传进来的id比当前节点小,往左子树找if(id<root->data.id)return find(root->l,id);//传进来的id比当前节点大,往右子树找return find(root->r,id);
}
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("  ");//画根节点print_s1(&root->data);//画左子树draw_(root->l,level+1);}
void draw(struct node_st *root)
{//根据层数画出树和空格draw_(root,0);
}
int main()
{int arr[]={1,2,3,7,6,5,9,8,4};int i;struct node_st *tree=NULL;struct score_st tmp,*datap;for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++){tmp.id=arr[i];snprintf(tmp.name,NAMESIZE,"stu%d",arr[i]);tmp.math=rand()%100;tmp.chinese=rand()%100;//无头节点要改变指针的指向,传二级指针insert(&tree,&tmp);}draw(tree);#if 0//查找测试int tmpid=1;datap=find(tree,tmpid);if(datap==NULL)printf("Can not find the id %d!\n",tmpid);else print_s1(datap);#endifreturn 0;
}

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

相关文章

Win11 配置 TeXstudio 编辑器教程

以下是关于在 Windows 11 系统上配置 TeXstudio 编辑器以使用 LaTeX 的教程。文章从安装必要的组件到实际测试的过程进行了详细的说明。 一、简介 在 Windows 11 上使用 LaTeX 需要完成以下两步&#xff1a; 选择一个 TeX 发行版并安装&#xff08;本文以 TeX Live 为例&…

构建高效可靠的分布式推理系统:深入解析控制器与模型服务的协同工作

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

基于遗传优化ELM网络的时间序列预测算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于遗传优化ELM网络的时间序列预测算法&#xff0c;分别对比ELM网络和GA-ELM网络对时间序列的预测精度进行对比。 2.测试软件版本以及运行结果展示 MATLAB2022…

算法日记 45 day 图论(并查集基础)

并查集解决什么问题 并查集常用来解决连通性问题。 大白话就是当我们需要判断两个元素是否在同一个集合里的时候&#xff0c;我们就要想到用并查集。 原理 既然是查找是否在同一个集合中&#xff0c;那么这个集合是怎么构建的呢&#xff1f;用一维数组来表示一个有向图&…

解读Modbus TCP指令

解读Modbus TCP指令&#xff1a;[0x01, 0x00, 0x00, 0x00, 0x04, 0x06, 0x01, 0x10, 0x00, 0xC8, 0x00, 0x02, 0x04, 0x00, 0x01, 0x00, 0x01] 在Modbus TCP通信中&#xff0c;数据以字节流的形式传输。理解和解析这些字节对于调试和开发至关重要。本文将详细解析给定的Modbus…

探索Spring之利剑:ApplicationContext接口

嘿&#xff0c;开发者们&#xff01;你是否曾在构建Spring应用时&#xff0c;感到困惑于那些复杂的配置和神秘的容器&#xff1f;今天&#xff0c;我们将揭开Spring中一个核心接口——ApplicationContext​的神秘面纱。这不仅是一篇技术文章&#xff0c;更是一次深入Spring心脏…

Electromagnetic Tracking Smart Car based on STM32F401 or GD32F450ZGT6

Electromagnetic Smart Car1 基于梁山派的电磁循迹智能车的主控芯片来自立创梁山派板载的国产兆易创新GD32F450ZGT6&#xff0c;整车采用模块化开发&#xff0c;由电源模块、L298N驱动模块、电磁循迹模块、梁山派、调试模块和显示模块组成。 嵌入式软件开发环境是&#xff1a;K…

加速合并,音频与字幕的探讨

因上一节。合并时速度太慢了。显卡没用上。所以想快一点。1分钟的视频用了5分钟。 在合并视频时,进度条中的 now=None 通常表示当前处理的时间点没有被正确记录或显示。这可能是由于 moviepy 的内部实现细节或配置问题。为了加快视频合并速度并利用 GPU 加速,可以采取以下措…