【C语言 数据结构】树

news2024/11/17 5:44:23

文章目录

    • 一、树的概念
    • 二、树的应用
      • 1)树可表示具有分枝结构关系的对象
      • 2)树是常用的数据组织形式
    • 三、树的表示
    • 四、树的基本术语
    • 五、树的四种表示方法
      • 5.1 双亲表示法
      • 5.2 孩子表示法
      • 5.3 双亲孩子表示法
      • 5.4 孩子兄弟表示法


一、树的概念

树形结构是一种重要的非线性结构,讨论的是层次和分支关系。

树是n个节点的有限集合,在任一棵非空树中:

(1)有且仅有一个称为根的节点。

(2)其余节点可分为n-1个互不相交的集合,而且这些集合中的每一集合都本身又是一棵树,称为根的子树。

  • 树是递归结构,在树的定义中又用到了树的概念

例:下面的图是一棵树

在这里插入图片描述

T = {A, B, C, D, E, F, G, H, I, J,K,L,M}

  • A是根,其余节点可以划分为3个互不相交的集合:

  • T1={B, E, F,K,L} 、 T2={C, G} 、T3={D, H, I, J,M}

这些集合中的每个集合都本身又是一棵树,它们是A的子树。例如对于 T1而言,B是根,其余节点可以划分为2个互不相交的集合:T11={E,K,L},T12={F},T11,T12又是B的子树。

从逻辑结构看:

1)树中只有根节点没有前趋节点;

2)除根节点外,其余节点都有且仅一个前趋;

3)树的节点,可以有零个或多个后继;

4)除根节点外的其他节点,都存在唯一条从根节点到该节点的路径;

5)树是一种分枝结构 (除了一个称为根的节点外)每个元素都有

且仅有一个直接前趋,有且仅有零个或多个直接后继。


二、树的应用

1)树可表示具有分枝结构关系的对象

例1.家族族谱

设某家庭有13个成员A、B、C、D、E、F、G、H、I、J,K,L,M。他们之间的关系可下图所示的树表示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3hrSikJB-1672620593479)(https://gcore.jsdelivr.net/gh/Code-for-dream/Blogimages/img/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/image-20221212105317737.png#pic_center)]

例2.单位行政机构的组织关系

2)树是常用的数据组织形式

有些应用中数据元素之间并不存在间分支结构关系,但是为了便于管理和使用数据,将它们用树的形式来组织。

例3 . 计算机的文件系统

不论是DOS文件系统还是window文件系统,所有的文件是用树的形式来组织的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tV1bU5TJ-1672620593479)(https://gcore.jsdelivr.net/gh/Code-for-dream/Blogimages/img/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/image-20221212105510846.png#pic_center)]


三、树的表示

在这里插入图片描述

1)图示表示

2)二元组表示

3)嵌套集合表示

4)凹入表示法(类似书的目录)

5)广义表表示


四、树的基本术语

在这里插入图片描述

树的节点:包含一个数据元素及若干指向子树的分支;

祖先节点:从根到该节点的所经分支上的所有节点,也就是当前节点的所有迭代父节点。

双亲节点:B 节点是A节点的孩子,则A节点是B节点的双亲(父节点);

兄弟节点:同一双亲(父节点)的孩子节点;

堂兄节点:节点深度相同,但父节点不同,则它们是一对堂兄弟节点;

孩子节点:节点的子树的根称为该节点的孩子;

子孙节点:以某节点为根的子树中任一节点都称为该节点的子孙

节点层:根节点的层定义为1;根的孩子为第二层节点,依此类推;

树的深度:树中最大的节点层(层数)

节点的度:节点子树的个数

树的度: 树中最大的节点度

叶子节点:也叫终端节点,是度为 0 的节点;

分枝节点:度不为0的节点;

有序树:子树有序的树,如:家族树;

无序树:不考虑子树的顺序;

森林:互不相交的树集合;森林和树之间的联系是:一棵树去掉根,其子树构成一个森林;一个森林增加一个根节点成为树。

二叉树:每个节点最多含有两个子树的树称为二叉树;

满二叉树:叶节点除外的所有节点均含有两个子树的树被称为满二叉树

完全二叉树:有个节点的满二叉树称为完全二叉树

哈夫曼树(最优二叉树):带权路径最短的二叉树称为哈夫曼树或最优二叉树

五、树的四种表示方法

先分别说下三种不同的表示法:双亲表示法、孩子表示法、双亲孩子表示法、孩子兄弟表示法

5.1 双亲表示法

  • 双亲表示法:一般采用顺序存储方式;

    • 以一组连续的空间存储树的结点,同时在每一个结点中附设一个指示器指示其双亲结点在链表中的位置

    • #define MAX_TREE_SIZE 100
      
      typedef struct PTNode{   //结点结构
          TElemTye data;       //数据元素类型
          int parent;          //双亲结点域
      }PTNode;
      
      typedef struct {                //树结构
          PTNode nodes[MAX_TREE_SIZE];//存储的结点
          int r,n;                    //根的位置和节点数
      }PTNode;
      

示意图:

在这里插入图片描述

代码实现:

/**
 * File : Work2.c
 * Author: 骑着蜗牛ひ追导弹'
 * Date: 2022/12/13 
 */
#include<stdio.h>

#define MAX_TREE_SIZE 100 //树中最多结点数
#define NodeNum 11 //总的结点数
typedef char ElemType;
typedef struct { //树的结点定义
    ElemType data; //数据元素
    int parent; //双亲位置域
} PTNode;
typedef struct { //树的类型定义
    PTNode nodes[MAX_TREE_SIZE]; //双亲表示
    int n; //结点数
} PTree;

void CreateTree(PTree *t) {
    int i, loc,tmp;
    ElemType ch;
    for (i = 0; i < NodeNum; i++) {
        printf("输入结点信息:");
        scanf("%c", &ch);
        t->nodes[i].data = ch;
        tmp = getchar();
        printf("输入对应双亲的位置下标:");
        scanf("%d", &loc);
        t->nodes[i].parent = loc;
        tmp = getchar();
        printf("\n");
    }
}

int main() {
    PTree *t;
    int i, j;
    CreateTree(t);
    printf("输出各结点的连接情况:\n");
    for (i = 0; i < NodeNum; i++) {
        printf("%c", t->nodes[i].data);
        for (j = 0; j < NodeNum; j++) {
            if (t->nodes[j].parent == i) printf(" -%c", t->nodes[j].data);
        }
        printf("\n");
    }
    return 0;
}

在这里插入图片描述

返回顶部


5.2 孩子表示法

  • 孩子表示法:采用顺序存储+链式存储;

    • 把每个结点的孩子结点排列起来,看成一个线性表,并且以单链表做存储结构,则n个结点有n个孩子链表(叶子节点的孩子链表为空表),而n个头结点又组成一个线性表。

    • #define MAX_TREE_SIZE 100
      
      typedef struct CTNode{  //孩子结点
          int child;          //孩子数
          struct CTNode* next;//下一个孩子结点指针
      }* ChildPtr;
      
      typedef struct{
          TElemType data;     //数据域
          ChildPtr firstChild;//孩子链表头指针
      }CTBox;
      
      typedef struct{
          CTBox nodes[MAX_TREE_SIZE];//存储的结点
          int n,r;                   //结点数和根的位置
      }
      

示意图:

在这里插入图片描述

代码实现:

/**
 * File : Work2_haizi.c
 * Author: 骑着蜗牛ひ追导弹'
 * Date: 2022/12/13 
 */

#include<stdio.h>
#include<malloc.h>

#define MAX_TREE_SIZE 100
#define NodeNum 11
typedef char ElemType;
typedef struct CTNode { //孩子结点
    int child; //孩子结点在数组中的位置
    struct CTNode *next; //下一个孩子
} CTNode;

typedef struct { //顺序存储表
    ElemType data;
    struct CTNode *firstChild; //第一个孩子
} CTBox;

typedef struct {
    CTBox nodes[MAX_TREE_SIZE];
    int n, r; //结点数和根的位置
} CTree;

void CreateBox(CTree *t) {
    int i;
    ElemType ch;
    printf("输入结点信息:");
    for (i = 0; i < NodeNum; i++) {
        scanf("%c", &ch);
        t->nodes[i].data = ch;
        t->nodes[i].firstChild = NULL;
    }

}

void CreateNodes(CTree *t, ElemType ch, int num) {
    CTNode *p, *r = t->nodes[0].firstChild;
    int i, j, k = 0;
    while (num--) {
        p = (CTNode *) malloc(sizeof(CTNode));
        p->next = NULL;
        printf("输入孩子结点的编号:");
        scanf("%d", &i);
        for (j = 0; j < NodeNum; j++)
            if (t->nodes[j].data == ch) k = j;
        if (i != k) {
            p->child = i;
            if (t->nodes[k].firstChild == NULL) {
                t->nodes[k].firstChild = p;
                r = p;
            } else {
                r->next = p;
                r = p;
            }
        }
    }
}


int main() {
    CTree t;
    CTNode *p;
    int i, num;
    CreateBox(&t);
    printf("\n");
    for (i = 0; i < NodeNum; i++) {
        printf("创建结点%c的孩子结点\n", t.nodes[i].data);
        printf("输入要创建的孩子结点个数:");
        scanf("%d", &num);
        CreateNodes(&t, t.nodes[i].data, num);
        printf("\n");
    }

    printf("输出各结点的连接情况:\n");
    for (i = 0; i < NodeNum; i++) {
        p = t.nodes[i].firstChild;
        printf("%d(%c)", i, t.nodes[i].data);
        while (p != NULL) {
            printf("-%d(%c) ", p->child, t.nodes[p->child].data);
            p = p->next;
        }
        printf("\n");
    }
    return 0;
}

在这里插入图片描述

返回顶部


5.3 双亲孩子表示法

  • 孩子表示法:采用顺序存储+链式存储;

    • 表中第一列为结点编号,第二列为结点数据,第三列为该节点的双亲编号(根节点双亲为-1),后面的单链表表示了该节点所有的孩子,从左至右依次进行遍历。

    • #define MAX_TREE_SIZE 100
      
      typedef struct CTNode{  //孩子结点
          int child;          //孩子数
          struct CTNode* next;//下一个孩子结点指针
      }* ChildPtr;
      
      typedef struct{
          TElemType data;     //数据域
          int parent;         //双亲下标
          ChildPtr firstChild;//孩子链表头指针
      }CTBox;
      
      typedef struct{
          CTBox nodes[MAX_TREE_SIZE];//存储的结点
          int n,r;                   //结点数和根的位置
      }
      

示意图:
在这里插入图片描述

代码实现:

/**
 * File : Work2_shuangqinhaizi.c
 * Author: 骑着蜗牛ひ追导弹'
 * Date: 2022/12/15 
 */

#include<stdio.h>
#include<malloc.h>

#define MAX_TREE_SIZE 100
#define NodeNum 11
typedef char ElemType;
//孩子链表结点
typedef struct CTNode {
    int child;           //孩子结点在数组中的位置
    struct CTNode *next; //下一个孩子
} CTNode;

//顺序存储表
typedef struct {
    ElemType data;    // 数据域
    int parent;       // 双亲位置
    struct CTNode *firstChild; //第一个孩子
} CTBox;
typedef struct {
    CTBox nodes[MAX_TREE_SIZE];
    int n, r; //结点数和根的位置
} CTree;

// 创建顺序表
void CreateBox(CTree *t) {
    int i,p;
    ElemType ch;
    printf("输入结点信息:");
    for (i = 0; i < NodeNum; i++) {
        scanf("%c", &ch);
        t->nodes[i].data = ch;
        t->nodes[i].firstChild = NULL;
    }
    printf("输入双亲结点信息:\n");
    for (i = 0; i < NodeNum; i++) {
        scanf("%d", &p);
        t->nodes[i].parent = p;
    }
}

void CreateNodes(CTree *t, ElemType ch, int num) {
    CTNode *p, *r = t->nodes[0].firstChild;
    int i, j, k = 0;
    while (num--) {
        p = (CTNode *) malloc(sizeof(CTNode));
        p->next = NULL;
        printf("输入孩子结点的编号:");
        scanf("%d", &i);
        for (j = 0; j < NodeNum; j++)
            if (t->nodes[j].data == ch) k = j;
        if (i != k) {
            p->child = i;
            if (t->nodes[k].firstChild == NULL) {
                t->nodes[k].firstChild = p;
                r = p;
            } else {
                r->next = p;
                r = p;
            }
        }
    }
}


int main() {
    CTree t;
    CTNode *p;
    int i, num;
    CreateBox(&t);
    printf("\n");
    for (i = 0; i < NodeNum; i++) {
        printf("创建结点%c的孩子结点\n", t.nodes[i].data);
        printf("输入要创建的孩子结点个数:");
        scanf("%d", &num);
        CreateNodes(&t, t.nodes[i].data, num);
        printf("\n");
    }

    printf("输出各结点的连接情况:\n");
    for (i = 0; i < NodeNum; i++) {
        p = t.nodes[i].firstChild;
        printf("%d(%c)[%d]", i, t.nodes[i].data,t.nodes[i].parent);
        while (p != NULL) {
            printf("-%d(%c) ", p->child, t.nodes[p->child].data);
            p = p->next;
        }
        printf("\n");
    }
    return 0;
}

在这里插入图片描述

返回顶部


5.4 孩子兄弟表示法

  • 孩子兄弟表示法:采用链式存储,(其实是一个二叉链表,相当于构建二叉树)

    • 又称二叉树表示法,或者二叉链表表示法。链表中结点的两个链域分别指向该节点的第一个孩子结点和下一个兄弟结点

    • typedef struct CSNode{
          TElemType data;
          struct CSNode *firstChild, *nextSibling;
      }CSNode , *CSTree;
      

示意图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jveCN7Oq-1672620593482)(https://gcore.jsdelivr.net/gh/Code-for-dream/Blogimages/img/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/image-20221215160752736.png#pic_center)]

代码实现:

/**
 * File : Work1.c
 * Author: 骑着蜗牛ひ追导弹'
 * Date: 2022/12/13 
 */
# include <stdio.h>
# include <stdlib.h>

typedef char nodeType;
typedef struct Tree {
    nodeType data;  // 数据域
    struct Tree *left;
    struct Tree *right;
} Tree, *BitTree;

BitTree createLink() {
    BitTree tree; // 二叉树
    char data;  // 节点数据
    char tmp;

    scanf("%c", &data);
    // 前面的scanf()在读取输入时会在缓冲区中留下一个字符’\n’(输入完按回车键所致),
    // 所以如果不在此加一个getchar()把这个回车符取走的话,
    // 接下来的scanf()就不会等待从键盘键入字符,
    // 而是会直接取走这个“无用的”回车符,从而导致读取有误
    tmp = getchar(); // 吸收空格

    if (data == '#') {
        return NULL; // 当前节点不存在数据
    } else {
        tree = (BitTree) malloc(sizeof(Tree)); // 分配空间
        tree->data = data;                    // 存储节点数据
        printf("请输入%c的左子树:", data);
        tree->left = createLink();            // 开始递归创建左子树
        printf("请输入%c的右子树:", data);
        tree->right = createLink();           // 开始到上一级节点的右边递归创建左右子树
        return tree;  // 返回根节点
    }
}

// 先序遍历
void showXianXu(BitTree T) {
    if (T == NULL) return; // 遇到空返回上一层节点
    printf("%c ", T->data);
    showXianXu(T->left); // 递归遍历左子树
    showXianXu(T->right);// 递归遍历右子树
}

// 中序遍历
void showZhongXu(BitTree T) {
    if (T == NULL) return; // 遇到空返回上一层节点
    showZhongXu(T->left); // 递归遍历左子树
    printf("%c ", T->data);
    showZhongXu(T->right);// 递归遍历右子树
}


// 后序遍历
void showHouXu(BitTree T) {
    if (T == NULL) return; // 遇到空返回上一层节点
    showHouXu(T->left); // 递归遍历左子树
    showHouXu(T->right);// 递归遍历右子树
    printf("%c ", T->data);
}



int main() {

    BitTree S;
    printf("请输入第一个节点的数据:\n");
    S = createLink();

    printf("先序遍历结果:\n");
    showXianXu(S);
    printf("\n中序遍历结果:\n");
    showZhongXu(S);
    printf("\n后序遍历结果:\n");
    showHouXu(S);

    return 0;
}

在这里插入图片描述

返回顶部


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/133983.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git基础知识学习

1. Git工作机制 Workspace&#xff1a; 工作区&#xff0c;就是你平时存放项目代码的地方Index / Stage&#xff1a; 暂存区&#xff0c;用于临时存放你的改动&#xff0c;事实上它只是一个文件&#xff0c;保存即将提交到文件列表信息Repository&#xff1a; 仓库区&#xff0…

CleanMyMac4.12.3全新版本Mac清理优化工具

CleanMyMac X是一款超好用的Mac清理优化工具&#xff0c;可以帮助用户删除系统垃圾、不需要的应用程序和恶意软件&#xff0c;并调整您的 Mac 以获得最大速度&#xff01; CleanMyMac X作为一款知名的系统清理软件&#xff0c;深受广大用户们的喜爱。它操作简洁&#xff0c;能够…

Mycat2(三)mycat2搭建读写分离

文章目录一、mycat一主一从读写分离原理二、搭建MySQL主从复制三、配置mycat2一主一从读写分离四、配置Mycat2双主双从读写分离4.1 Mysql 双主双从搭建步骤1、创建MySQL数据库与MySQL 机器信息2、双柱双从配置2.1 master1配置2.2 master2配置2.3 Slave1、Slave2 配置3、在两台主…

程序员如何在职场上走得更远一些?

一. 工作心态 首先第一个要聊的啊就是这个心态的问题&#xff0c;我觉得有时候可以改变一下自己的心态&#xff0c;可以尝试把工作当成一种投资&#xff0c;或者说呢把工作当成一种自己的产品来经营&#xff0c;把目光多多的聚焦在这个收获和成长上面啊这样一个心态来应对&…

KV数据分片和分布

KV数据分片和分布 KV存储数据组织方式 Hash&#xff1a;对于Hash方式&#xff0c;键值对数据的存储位置由预定义的Hash函数确定&#xff0c;因此所有键值对数据不是有序排列。Hash方式的优点是通过Hash函数计算存储位置的效率高&#xff0c;因此处理插入、删除、更新、单点查…

MySQL之事务

引入事务&#xff1a; 一个事务其实就是一个完整的业务逻辑&#xff0c;它是一个最小的工作单元&#xff0c;是不可再分的。 那么什么是一个完整的业务逻辑呢&#xff1f; 拿现实生活中的银行业务举例&#xff0c;假设转账&#xff0c;从A账户向B账户中转账10000&#xff0c…

Redis:一、简介

Redis 1. redis的简介 1.1 NoSQL的介绍 在介绍redis之前&#xff0c;我们先来了解一下NoSQL(Not only SQL)&#xff0c;不仅仅是SQL。 NoSQL&#xff0c;泛指非关系型的数据库。随着互联网web2.0网站的兴起&#xff0c;传统的关系型数据库在应付web2.0网站&#xff0c;特别…

Cache(缓存)基本概念

cache的概念在计算机中被广泛应用&#xff0c;包括TLB等都使用了它的理念&#xff0c;因此对其进行总结。Cache——位于CPU上&#xff0c;处于寄存器和内存之间的存储单元。 Cache Hit & Miss在写入cache的时候&#xff0c;有hit&#xff08;命中&#xff09;和miss&#x…

基于ros1的 apollo 7.0.0规划控制算法

apollo.ros-7.0.0 上次给大家带来了之前学习apollo时开发的内容apollo.ros-1.0.0和apollo.ros-3.0.0&#xff0c;主要是针对apollo 1.0.0和3.0.0版本进行了ros1下的移植和规划控制算法的学习。本次在之前工作的基础上&#xff0c;针对apollo 7.0.0版本&#xff0c;进行了ros1下…

植物大战僵尸:分析植物的攻击速度

植物大战僵尸中&#xff0c;植物是有攻击速度的&#xff0c;比如每隔一段时间会吐出一些子弹&#xff0c;那么由此可判断吐出子弹应该是由一个计数器控制的&#xff0c;也就是说只要我们能够找到控制植物攻击的时钟并改写它&#xff0c;也就可以实现植物的无限吐子弹。 吐出子…

数据结构---二叉树

坚持看完&#xff0c;结尾有思维导图总结 这里写目录标题什么是二叉树&#xff1f;二叉树的定义二叉树的性质二叉树的基石在哪里?总结什么是二叉树&#xff1f; 二叉树的定义 二叉树&#xff0c;就是从一个根开始&#xff0c;按照两边分支的方式向下生长的树&#xff0c;就能…

python虚拟环境的概念,用法(pycharm)

1.在PyCharm中创建python项目时&#xff0c;需要配置python的运行环境&#xff0c;除了使用系统现有环境以外&#xff0c;还可以创建虚拟环境。 2.虚拟环境的创建是因为在实际开发中需要同期用到不同版本的python解释器&#xff0c;不同的第三方库以及同一个第三方库的不同版本…

Qt音视频开发08-ffmpeg内核优化(极速打开/超时回调/实时响应)

一、前言 最初编写这套视频解析组件的时候&#xff0c;面对的场景是视频监控行业&#xff0c;对应设备都是网络监控摄像机&#xff0c;传过来的都是rtsp这种视频流&#xff0c;做过这一块的人都知道&#xff0c;打开某个视频流默认耗时比较大&#xff0c;基本上在2s左右&#…

高级前端二面手写面试题(边面边更)

解析 URL Params 为对象 let url http://www.domain.com/?useranonymous&id123&id456&city%E5%8C%97%E4%BA%AC&enabled; parseParam(url) /* 结果 { user: anonymous,id: [ 123, 456 ], // 重复出现的 key 要组装成数组&#xff0c;能被转成数字的就转成数字…

四【Servlet基础】文件配置及环境搭建(重要)

文章目录4.1 Servlet概念4.2 Servlet作用4.3 Servlet开发步骤4.3.1 搭建开发环境4.3.2 创建项目4.3.3 部署Servlet4.3.4 配置Servlet4.3.5 测试运行4.1 Servlet概念 &#xff08;1&#xff09;Servlet&#xff1a;Server Applet的简称&#xff0c;是运行在Web服务器端的Java程…

GDB无法debug的错误

GDB无法debug的错误 一、输出错误信息描述 Warning: opening /proc/PID/mem file for lwp 707.707 failed: No such file or directory (2) Warning: Cannot insert breakpoint 1. Cannot access memory at address 0x806950 二、解决方法 方法&#xff1a;修改 GDB 的二进…

spring之IoC注解(三)负责注入的注解

文章目录前言一、Value注解Product类spring配置文件测试程序运行结果二、Autowired与Qualifier注解1.创建OrderDao接口2.创建OrderDao接口实现类3.创建OrderService类4.配置文件5.测试程序6.运行结果三、Resource注解&#xff08;重要&#xff09;1、创建StudentDao接口2、创建…

皮带断裂识别检测系统 opencv

皮带断裂识别检测系统通过opencv深度学习yolo计算机视觉识别技术对皮带运行状态进行全天候实时监测&#xff0c;当识别到皮带断裂撕裂时立即抓拍告警存档。OpenCV-Python是一个Python绑定库&#xff0c;旨在解决计算机视觉问题。OpenCV-Python使用Numpy&#xff0c;这是一个高度…

LeetCode刷题复盘笔记—一文搞懂动态规划之392. 判断子序列问题(动态规划系列第三十八篇)

今日主要总结一下动态规划的一道题目&#xff0c;392. 判断子序列 题目&#xff1a;392. 判断子序列 Leetcode题目地址 题目描述&#xff1a; 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&a…

08 LIN

基础知识 LIN的全称为Local Interconnect Network。LIN主要功能是为CAN总线网络提供辅助功能&#xff0c;应用场合有智能传感节点、自动车窗节点等。 硬件 特点 1.采用单主多从的组网方式&#xff0c;无CAN总线那样的仲裁机制&#xff0c;最多可连接16个节点&#xff08;1主…