C语言链表、树、图的实现(结构体)

链表、树、图

    • 链表
      • 邻接矩阵
      • 邻接表

链表

参看此线性表实现(C语言——结构体)博文

struct Tree{int val;struct Tree *left;struct Tree *right;
};

在上面的代码中,每一部分都是定义二叉树节点所必需的,所以没有多余的可以删除的部分。但是,如果你想简化代码或使其更加清晰,你可以考虑下面:

使用typedef的同时定义结构体,这样可以避免在结构体内部重复使用struct关键字。这是C语言中常见的做法:

typedef struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;
} TreeNode;

在这个例子中,虽然你在结构体内部还是用了struct TreeNode,但是在定义完结构体之后,你可以直接使用TreeNode来声明变量,而不需要再次使用struct关键字。

然而,有些C编译器(如GCC和Clang)支持一种扩展语法,允许你在typedef的同时,也在结构体内部使用新定义的别名,而不需要前缀struct。这种写法在C++中是标准的,但在C中只是某些编译器的扩展:

typedef struct TreeNode {int val;TreeNode *left;  // 注意这里直接使用TreeNode而不是struct TreeNodeTreeNode *right; // 同上
} TreeNode;

如果你确定你的编译器支持这种扩展语法,并且你希望代码更加简洁,你可以选择使用这种写法。但是,为了保持代码的可移植性,最好还是坚持使用标准的C语法,即在结构体内部使用struct TreeNode

总结来说,你的原始代码已经是定义二叉树节点的标准方式,没有任何可以删除的部分,除非你打算使用编译器的特定扩展。

示例

#include<stdio.h>
#include<stdlib.h>
typedef struct TreeNode{int data;TreeNode *left;TreeNode *right;
};
void start(TreeNode *p,int a){p->data=a;p->left=NULL;p->right=NULL;
} 
void addleft(TreeNode *p, TreeNode *a,int b){p->left=a;a->data=b;a->left=NULL;a->right=NULL;
} 
void addright(TreeNode *p, TreeNode *a,int b){p->right=a;a->data=b;a->left=NULL;a->right=NULL;
} 
void Xian(TreeNode *p){if(p!=NULL){printf("%d",p->data);Xian(p->left);Xian(p->right);}
}
void Zhong(TreeNode *p){if(p!=NULL){Xian(p->left);printf("%d",p->data);Xian(p->right);}
}
void Hou(TreeNode *p){if(p!=NULL){Xian(p->left);Xian(p->right);printf("%d",p->data);}
}
//判断两棵树是否相同 
bool isSameTree(TreeNode* p, TreeNode* q){if(p==NULL&&q==NULL){return true;}else if(p==NULL||q==NULL){return false;}else if(p->data!=q->data){return false;}else{return isSameTree(p->left,q->left)&&(p->right,q->right);}
}
int main(){	TreeNode *root;TreeNode *left;TreeNode *right;root=(TreeNode *)malloc(sizeof(TreeNode));left=(TreeNode *)malloc(sizeof(TreeNode));right=(TreeNode *)malloc(sizeof(TreeNode));start(root,3);addleft(root,left,4);addright(root,right,5);printf("%d\n",root->left->data); Xian(root);printf("\n");Zhong(root);printf("\n");Hou(root);free(root);free(left);free(right);return 1; 
}

对图的定义都需要提前确定定点数或者设置一个较大的定点数,然后不超过此范围即可

邻接矩阵

#define MAXVEX 10
#define MAX 65525//顶点之间不可达一般设为一个很大的数或者零
typedef struct MGraph{char vexs[MAXVEX];//设置顶点信息,由于是以为字符串数组所以只有单字母标识顶点即A,B顶点等int arc[MAXVEX][MAXVEX];//临界矩阵int numVertexes;//定点数int numEdge;//边数
}MGraph; 

示例

#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 10
#define MAX 65525
int visited[MAXVEX];typedef struct MGraph{char vexs[MAXVEX];int arc[MAXVEX][MAXVEX];int numVertexes;int numEdge;
}MGraph; 
//初始化图 
void start(MGraph *G){printf("请输入顶点数和边数:\n");scanf("%d,%d",&(G->numVertexes),&(G->numEdge));getchar();int a=0;printf("输入各顶点信息:\n");for(a;a<G->numVertexes;a++){scanf("%c",&(G->vexs[a]));getchar();}int i,j;//初始化矩阵 for(i=0;i<MAXVEX;i++){for(j=0;j<MAXVEX;j++){if(i==j){G->arc[i][j]=0;}else{G->arc[i][j]=MAX;}}} int m,n,b;	//	不带权值 
//	printf("输入存在的边:\n");
//	for(b=0;b<G->numEdge;b++){
//		scanf("%d,%d",&m,&n);
//		//无向图,两顶点间互通
//		G->arc[m][n]=G->arc[n][m]=1;
//		//有向图,单向通 
//		//G->arc[m][n]=1;
//	}//  带权值 printf("输入存在的边以及对应的权值:\n");for(b=0;b<G->numEdge;b++){int q;scanf("%d,%d,%d",&m,&n,&q);//无向图,两顶点间互通G->arc[m][n]=G->arc[n][m]=q;//有向图,单向通 //G->arc[m][n]=1;} 
}
//深度优先搜索 --邻接矩阵 
void DFS(MGraph *G,int i){visited[i]=1;printf("当前节点为:%c\n",G->vexs[i]);int j;for(j=0;j<G->numVertexes;j++){if(G->arc[i][j]&&visited[j]==0){DFS(G,j);}} 
} 
//深度优先遍历 --邻接矩阵  
void DFSTraverse(MGraph *G,int i){if(G->numVertexes<1){printf("该图没有顶点。");return; }int j;for(j=0;j<G->numVertexes;j++){visited[j]=0;}for(j=0;j<G->numVertexes;j++){if(!visited[j]){DFS(G,i);}}printf("遍历结束!");
} 
int main(){struct MGraph *G;G=(MGraph *)malloc(sizeof(MGraph));start(G);//遍历图 DFSTraverse(G,1);return 1;
} 
/*
输入示例: 
邻接矩阵
请输入顶点数和边数:
7,10
输入各顶点信息:
A
B
C
D
E
F
G
输入存在的边:
0,1
0,2
0,3
1,6
1,4
2,4
2,5
3,6
3,5
4,5
带权值 
0,1,1
0,2,4
0,3,10
1,6,7
1,4,6
2,4,9
2,5,2
3,6,5
3,5,8
4,5,11
*/

邻接表

typedef struct EdgeNode{ int data;//存储顶点下标; int weight;//有向图的权值; struct EdgeNode *next; //指向下一个邻接点 
}EdgeNode; 
//顶点数组 
typedef struct VertexNode{char data;//存储顶点信息; struct EdgeNode *first;//边表的头节点; 
}VertexNode,AdjList[MAXVEX];
//图的邻接表 
typedef struct GraphAdjList{AdjList adjlist;int numVertexes,numEdge;//当前顶点数和边数 
}GraphAdjList;

示例

#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100 
#define MAX 65525
int visited[MAXVEX];
//顶点的邻接点
typedef struct EdgeNode{ int data;//存储顶点下标; int weight;//有向图的权值; struct EdgeNode *next; //指向下一个邻接点 
}EdgeNode; 
//顶点数组 
typedef struct VertexNode{char data;//存储顶点信息; struct EdgeNode *first;//边表的头节点; 
}VertexNode,AdjList[MAXVEX];
//图的邻接表 
typedef struct GraphAdjList{AdjList adjlist;int numVertexes,numEdge;//当前顶点数和边数 
}GraphAdjList;
//初始化 
void start(GraphAdjList *G){EdgeNode *temp; printf("输入边数和顶点数:\n"); scanf("%d,%d",&(G->numEdge),&(G->numVertexes));getchar();int i,j,m;printf("输入各顶点信息:\n");for(i=0;i<G->numVertexes;i++){scanf("%c",&(G->adjlist[i].data));getchar();G->adjlist[i].first=NULL;}
//	不带权值的实现 
//	printf("输入存在的边:\n");
//	for(m=0;m<G->numEdge;m++){
//		scanf("%d,%d",&i,&j);
//		//无向图,两顶点互通; 
//		temp=(EdgeNode *)malloc(sizeof(EdgeNode));
//		temp->data=j;
//		temp->next=G->adjlist[i].first;
//		G->adjlist[i].first=temp;
//		
//		有向图不需要下面步骤 
//		temp=(EdgeNode *)malloc(sizeof(EdgeNode));
//		temp->data=i;
//		temp->next=G->adjlist[j].first;
//		G->adjlist[j].first=temp;
//		getchar();
//	}printf("输入存在的边:\n");for(m=0;m<G->numEdge;m++){scanf("%d,%d",&i,&j);//无向图,两顶点互通; 有向图只用第一个即可 temp=(EdgeNode *)malloc(sizeof(EdgeNode));temp->data=j;
//		printf("输入存在的边的权值:\n");scanf("%d",&temp->weight); temp->next=G->adjlist[i].first;G->adjlist[i].first=temp;temp=(EdgeNode *)malloc(sizeof(EdgeNode));temp->data=i;temp->next=G->adjlist[j].first;G->adjlist[j].first=temp;getchar();}
}
//深度优先搜索 --邻接表 
void DFS(GraphAdjList *G,int i){EdgeNode *p; visited[i]=1;printf("遍历节点为:%c\n",G->adjlist[i].data);p=G->adjlist[i].first;while(p){int j = p->data;if(!visited[j]){DFS(G,j);}p=p->next;}
} 
//深度优先遍历 --邻接表  
void DFSTraverse(GraphAdjList *G){if(G->numVertexes<1){printf("该图没有顶点。");return; }int j;for(j=0;j<G->numVertexes;j++){visited[j]=0;}for(j=0;j<G->numVertexes;j++){if(!visited[j]){DFS(G,j);}}
}
int main(){struct GraphAdjList *G;G=(GraphAdjList *)malloc(sizeof(GraphAdjList));start(G);DFSTraverse(G);
}
/*输入示例
邻接表
请输入顶点数和边数:
10,7
输入各顶点信息:
A
B
C
D
E
F
G
输入存在的边:
0,1
0,2
0,3
1,6
1,4
2,4
2,5
3,6
3,5
4,5
带权值 
0,1
1
0,2
4
0,3
10
1,6
7
1,4
6
2,4
9
2,5
2
3,6
5
3,5
8
4,5
6
*/

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

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

相关文章

VS2022 Android NativeActivity 开发指南

几年前最初使用VS时&#xff0c;记得是有Android NativeActivity的&#xff0c;今天更新到了2022最新版&#xff0c;发现找不到这个创建选项。 然后确保安装了C 跨平台开发工具后&#xff0c;开始排查原因。 Visual Studio 2022 中没有“本机活动应用程序” - android - SO中…

LeetCode1534. Count Good Triplets

文章目录 一、题目二、题解 一、题目 Given an array of integers arr, and three integers a, b and c. You need to find the number of good triplets. A triplet (arr[i], arr[j], arr[k]) is good if the following conditions are true: 0 < i < j < k < …

Doris数仓开发规范

文章目录 一、字符集规范二、建表规范三、数据变更规范四、数据查询规范结尾 一、字符集规范 【强制】数据库字符集指定utf-8&#xff0c;并且只支持utf-8。 二、建表规范 【建议】库名统一使用小写方式&#xff0c;中间用下划线&#xff08;_&#xff09;分割&#xff0c;长…

Android 车联网——CarPackageManagerService介绍(十一)

CarPackageManagerService 主要用于车上使用场景扩充了一些包管理相关的接口。包括黑白名单的机制,这主要是出于安全的考虑,车上的应用有更严格的限制。结合用户体验限制对运行在Android Automotive OS 上的应用有一个更好的约束。 一、简介 CarPackageManagerService 是 An…

力扣42. 接雨水

双指针法 思路&#xff1a; 将数组前后设置为 left、right 指针&#xff0c;相互靠近&#xff1b;在逼近的过程中记录两端最大的值 leftMax、rightMax&#xff0c;作为容器的左右边界&#xff1b;更新指针规则&#xff1a; 如果数组左边的值比右边的小&#xff0c;则更新 left…

使用GO开发的IDE简介

一、IDE介绍 Goland Goland是由JetBrains公司开发的商业IDE&#xff0c;专门为Go语言开发设计。JetBrains是一家知名的软件开发公司&#xff0c;以其强大的IDE产品如IntelliJ IDEA而闻名。 优点&#xff1a; 基于IntelliJ平台&#xff0c;因此拥有与IntelliJ IDEA相似的强大功能…

【Linux操作系统】探秘Linux奥秘:进程与任务管理的解密与实战

&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《操作系统实验室》&#x1f516;诗赋清音&#xff1a;柳垂轻絮拂人衣&#xff0c;心随风舞梦飞。 山川湖海皆可涉&#xff0c;勇者征途逐星辉。 目录 &#x1fa90;1 初识Linux OS &…

4462 4.曙曙献爱心

#include<bits/stdc.h> using namespace std; int n,m,k; int a[1001]; int s[1001]; int f[1001][1001];//f[i][j]&#xff0c;i个警察&#xff0c;j个点&#xff0c;能管理的最大人数 int main(){cin>>n>>m>>k;for(int i1;i<n;i){cin>>a[i…

【快慢指针】26.删除有序数组中的重复项

题目 法1&#xff1a;快慢指针 基础解法&#xff0c;必须掌握&#xff01;&#xff01;&#xff01; class Solution {public int removeDuplicates(int[] nums) {if (nums.length < 2) {return nums.length;}int slow 0, fast 1;while (fast < nums.length) {if (n…

大数据StarRocks(一) StarRocks概述

1 StarRocks介绍 StarRocks是新一代极速全场景MPP(Massively Parallel Processing)数据库&#xff0c;它充分吸收关系型OLAP数据库和分布式存储系统在大数据时代的优秀研究成果&#xff0c;在业界实践的基础上&#xff0c;进一步改进优化、升级架构&#xff0c;并增添了众多全…

前端知识点(面试可看) —— HTML

摘要 马上就要毕业啦&#xff0c;没有参加2023年的秋招&#xff0c;准备在最近开始找全职或者实习工作&#xff0c;然后也马上过年了&#xff0c;总结和理一下自己的知识要点&#xff0c;参加2024年的春招。 页面缩放 meta viewport 如何去使用&#xff0c;怎么使用&#xf…

TypeScript 语法 + 工具封装

环境配置 安装 npm install typescript -g 查看版本 tsc --version 1.初识typescript 邂逅typescript&#xff0c;typescript的基本使用 新建ts 文件 &#xff08;记得导出&#xff09; typescript 定义时可指定 变量类型 在名称后面加引号 和 类型 格式为 let 名称: 类型 …

Java学习,一文掌握Java之SpringBoot框架学习文集(2)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

Docker 安装Mysql

目录 Docker Mysql安装 ✨安装和配置mysql ✨远程连接mysql远程连接 MySQL 是世界上最流行的开源数据库。根据 DB-Engines的调查数据&#xff0c;MySQL 是第二受欢迎的数据库&#xff0c;仅次于 Oracle 数据库。MySQL在过去由于性能高、成本低、可靠性好&#xff0c;已经成…

Redis缓存保卫战:拒绝缓存击穿的进攻【redis问题 三】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Redis缓存保卫战&#xff1a;拒绝缓存击穿的进攻 前言缓存击穿的定义和原理为何会发生缓存击穿缓存击穿的危害防范缓存击穿结语: 前言 你是否曾经遇到过系统在高并发情况下出现严重性能问题&#xff…

2023.12.31力扣每日一题——一年中的第几天

2023.12.31 题目来源我的题解方法一 模拟 题目来源 力扣每日一题&#xff1b;题序&#xff1a;1154 我的题解 方法一 模拟 如果月份大于2,&#xff0c;需要判断当年是否是闰年&#xff0c;如果是闰年2月份需要多算一天。 具体计算&#xff1a; 先计算月的贡献&#xff08;注…

微信养号指南:提高账号权重

在如今的社交媒体时代&#xff0c;微信成为了人们生活中必不可少的一部分。它不仅是一个即时通讯工具&#xff0c;更是一个方便快捷的社交平台。然而&#xff0c;要想让自己的微信号保持活跃并吸引更多的关注&#xff0c;需要一些技巧和策略。下面将为大家分享一些微信养号指南…

云卷云舒:基于业务逻辑关联度实现数据预加载

云卷云舒&#xff1a;算力网络云原生&#xff08;下&#xff09;&#xff1a;云数据库发展的新篇章-CSDN博客 一、现有技术的技术方案 在实现一个具有复杂业务逻辑的应用系统时&#xff0c;大多数情况下&#xff0c;编码过程中必定会包含着较多的数据访问方法&#xff08;java…

MES是什么?有了MES还要上ERP或MES吗?

MES是什么 MES是Manufacturing Execution System&#xff08;制造执行系统&#xff09;的简称&#xff0c;是一套面向制造企业车间执行层的生产信息化管理系统&#xff0c;负责承接ERP系统下达的生产计划&#xff0c;与ERP关系密切。MES能通过信息传递&#xff0c;做到生产追溯…

亚马逊、速卖通等跨境平台如何利用自养号测评提升销量

一、自然排名&#xff1a;链接成功的关键 自然排名的重要性不言而喻。一个链接的成功与否&#xff0c;关键在于其自然排名是否能够打上来。无论是搜索流量还是关联流量的自然排名&#xff0c;亦或是BSR排行榜&#xff0c;都应时刻关注这些自然排名的变化。 二、自然排名的位置…