c_ 数据结构_图_邻接矩阵
程序主要实现了图的深度遍历和广度遍历。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OVERFLOW -2
#define ERROR 0
#define OK 1
#define Length (q.rear+1)%QUEUE_MAXSIZE //队满
#define MAX_VERtEX_NUM 20 //顶点的最大个数
#define QUEUE_MAXSIZE 100
#define Queue_increment 10 typedef struct QNode{
int data;
struct QNode *next;
}QNode,*QueuePtr; typedef struct{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
//-------------------------------------------------------------------------------------------------------------
typedef struct {
int adj; //对于无权图,用 1 或 0 表示是否相邻;对于带权图,直接为权值。
}ArcCell,AdjMatrix[MAX_VERtEX_NUM][MAX_VERtEX_NUM]; typedef struct {
char vexs[MAX_VERtEX_NUM]; //存储图中顶点数据
AdjMatrix arcs; //二维数组,记录顶点之间的关系
int vexnum,arcnum; //记录图的顶点数和弧(边)数
}MGraph;
//---------------------------------------------------------------------------
// 矩阵打印关系
void PrintGrapth(MGraph &G){
int i,j;
for (i = ; i < G.vexnum;++i){
printf("%d",G.vexs[i]);
}
printf("顶点间的关系:\n");
for (i = ; i < G.vexnum; ++i){
for (j = ; j < G.vexnum; ++j){
printf("%d ", G.arcs[i][j].adj);
}
printf("\n");
}
}
//---------------------------------------------------------------------------
//根据顶点本身数据,判断出顶点在二维数组中的位置
int LocateVex(MGraph &G,int v){
//遍历一维数组,找到变量v
for (int i=; i<G.vexnum; ++i) {
if (G.vexs[i]==v) {
return i;
}
}
return -; //如果找不到,返回-1
}
//构造无向图
int CreateDN(MGraph &G){
int i,j,k,m,n,x;int v1,v2;//char a[2];
printf("请输入总顶点数n和总边数:");
scanf("%d",&(G.vexnum)); // 输入总顶点数,总边数
scanf("%d",&(G.arcnum));
x=G.vexnum;
if(G.vexnum< && G.arcnum<=(x*(x-)/)){
printf("请(回车)输入 %d 个顶点的值:\n",G.vexnum);
for (i=; i<G.vexnum; i++) { // 循环输入顶点值
scanf("%d",&(G.vexs[i]));
}
for (i=; i<G.vexnum; ++i) { // 初始化邻接矩阵
for (j=; j<G.vexnum; ++j) {
G.arcs[i][j].adj=;
}
}
printf("\n请实现 %d 条边的连接:\n",G.arcnum);
for (k=;k<G.arcnum; ++k) { // 构造邻接矩阵
printf("\n请输入哪'两个'顶点要进行连接边:");
fflush(stdin);
scanf("%d",&v1);
n=LocateVex(G, v1); //定位顶点
scanf("%d",&v2);
m=LocateVex(G, v2);
while (m==-||n==-) {
printf("没有这样的顶点,请重新输入:");
fflush(stdin);
scanf("%d",&v1);
n=LocateVex(G, v1); //定位顶点
scanf("%d",&v2);
m=LocateVex(G, v2);
// if(m!=-1&&n!=-1){break; }
}
while(G.arcs[n][m].adj==){
printf("\n!!!两顶点已经被连接!!!\n");
printf("请重新输入两顶点:");
fflush(stdin);
scanf("%d",&v1);
n=LocateVex(G, v1); //定位顶点
scanf("%d",&v2);
m=LocateVex(G, v2);
// if(G.arcs[n][m].adj!=1){break; }
while (m==-||n==-) {
printf("没有这样的顶点,请重新输入:");
fflush(stdin);
scanf("%d",&v1);
n=LocateVex(G, v1); //定位顶点
scanf("%d",&v2);
m=LocateVex(G, v2);
// if(m!=-1&&n!=-1){break; }
}
}
G.arcs[n][m].adj=G.arcs[m][n].adj=; //无向图的二阶矩阵沿主对角线对称
}
}else{
printf("\n!!!您输入的总顶点数 大于 20 了或者是输入的总边数 不符合 n(n-1)/2 !!!\n");
CreateDN(G);
}
return OK;
}
//-------------------------------------------------------------------------------------------------
int visited[MAX_VERtEX_NUM]; // 辅助数组
// 遍历节点
void DFS(MGraph &G,int v){
int j;
printf("访问到顶点:%d\n\n",G.vexs[v]); // 表示顶点被访问过了
visited[v]=;
for(j=;j<G.vexnum;++j){
if(G.arcs[v][j].adj!= && visited[j]==){ // 如果有邻接点则继续递归
DFS(G,j);
}
}
} // 顶点的非连通图的深度遍历
int DFSTraverse(MGraph &G){
int n=,v,x,j,m;
for(v=;v<G.vexnum;v++) visited[v]=; // 把所有的标记置为0
printf("\n请输入遍历起点:\n");
scanf("%d",&x);
printf("遍历起点为:%d \n",x);
m = LocateVex(G,x);
if(m==-){
printf("\n!!!您输入的起点不在顶点表内!!!\n");
DFSTraverse(G);
}
//n=LocateVex(G,x);
visited[m]=;
for(j=;j<G.vexnum;++j){
if(G.arcs[n][j].adj!= && visited[j]==){ // 如果有邻接点则继续递归
DFS(G,j);
}
}
//DFS(G,m);
for(v=;v<G.vexnum;++v){ // 判断是否还有没有被遍历的图
if(visited[v]==){
DFS(G,v); // 调用DFS遍历单个图
}
}
return OK;
}
//-------------------------------------------------------------------------------------
//构建空队
int InitQueue_Q(LinkQueue &Q){
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front){
printf("队存储空间分配失败!!");
exit(OVERFLOW);
}
Q.front->next=NULL;
return OK;
}
//队尾插入元素
int EnQueue_Q(LinkQueue &Q,int &e){
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p){ //存储分配失败
printf("队存储空间分配失败!!!\n");
exit(OVERFLOW);
}
p->data=e; //e赋值给p指向的空间
p->next=NULL; //p指向NULL
Q.rear->next=p;
Q.rear=p; //将p赋给Q
return OK;
}
// 删除队列头元素
int DeQueue_Q(LinkQueue &Q,int &e){
QNode *P;
if(Q.front==Q.rear) return ERROR;
P=Q.front->next ;
e=P->data;
Q.front ->next =P->next; //将原对头的后继p->next赋值给头结点后继
if(Q.rear ==P) //当队列中只有一个元素时,q->rear指向头结点
Q.rear =Q.front;
free(P);
return OK;
}
// 队判空
int QueueEmpty(LinkQueue Q)
{
if(Q.front->next==NULL)
return ERROR;
else
return OK;
}
//-----------------------------------------------------------------------------------------------------
// BFSTraversed调用BFS每一个节点都被访问
void BFS(MGraph &G,int i){
int j;
LinkQueue Q;
InitQueue_Q(Q);
if(visited[i]==){ //未访问过该顶点
printf("访问到顶点:%d\n\n",G.vexs[i]);
visited[i]=; // 置1
EnQueue_Q(Q,i); //将其入队列
while(QueueEmpty(Q)){ // 循环队不为空QueueEmpty返回1
DeQueue_Q(Q,i); //将队头元素出队列,置为v
for(j=;j<G.vexnum;j++){
if(G.arcs[i][j].adj!= &&visited[j]==){ //未访问过的邻接点
printf("顶点走到的值:%d\n\n",G.vexs[j]); // i 为v中未被访问的邻接点
visited[j]=; // 访问置1
EnQueue_Q(Q,j); //入队列
}
}
}
}
}
// 广度优先遍历图
int BFSTraverse(MGraph &G)
{ int i,v,j,m;char x;
LinkQueue Q;
InitQueue_Q(Q);
for(v=;v<G.vexnum;v++){ // 辅助数组置零
visited[v]=;
}
printf("\n请输入遍历起点:\n");
scanf("%d",&x);
printf("遍历起点为:%d \n",x);
m=LocateVex(G,x);
if(m==-){
printf("\n!!!您输入的起点不在顶点表内!!!\n");
BFSTraverse(G);
}
visited[m]=;
EnQueue_Q(Q,m); //将其入队列
while(QueueEmpty(Q)){ // 循环队不为空QueueEmpty返回1
DeQueue_Q(Q,m); //将队头元素出队列,置为v
for(j=;j<G.vexnum;j++){
if(G.arcs[m][j].adj!= &&visited[j]==){ //未访问过的邻接点
printf("顶点走到的值:%d\n\n",G.vexs[j]); // i 为v中未被访问的邻接点
visited[j]=; // 访问置1
EnQueue_Q(Q,j); //入队列
}
}
}
for(i=;i<G.vexnum;i++){ // 保证所有节点被访问
BFS(G, i );
}
return OK;
}
//操作菜单
void OperateMenu(){ printf("\n\n--------------请选择元素处理方式---------\n\n");
printf("!!!!!注:测试程序过程中,输入应全为数字!!!!!\n\n");
printf("0> :退出\n\n");
printf("1>: 深度遍历\n\n");
printf("2>: 广度遍历\n\n");
printf("3>: 输出邻接矩阵\n\n");
printf("(注:选择过程中应为数字)\n\n");
printf("请选择对元素的处理:");
}
void main() {
MGraph G;//建立一个图的变量
int w=,k,boo=;
printf("请用户选择创建图 或 退出程序:\n\n");
printf("注:程序测试过程中输入应全为数字\n\n");
printf("创建图请输入:'1'\n\n");
printf("退出请选择'0'或 其它!!\n\n");
printf("请选择:");
scanf("%d",&w);
if(w==){
boo=CreateDN(G);
if(boo)
printf("\n建图成功!!!\n");
else
printf("\n建图失败!!!\n");
OperateMenu();
scanf("%d",&k);
while(k){
switch(k){
case :break;
case :boo=DFSTraverse(G); // 深度遍历
if(boo)
printf("\n深度遍历成功!!!\n");
else
printf("\n深度遍历失败!!!\n");
break;
case :boo=BFSTraverse(G); // 广度遍历
if(boo)
printf("\n广度遍历成功!!!\n");
else
printf("\n广度遍历失败!!!\n");
break;
case :PrintGrapth(G);
}
OperateMenu();
scanf("%d",&k);
}
}
}
c_ 数据结构_图_邻接矩阵的更多相关文章
- 数据结构(12) -- 图的邻接矩阵的DFS和BFS
//////////////////////////////////////////////////////// //图的邻接矩阵的DFS和BFS ////////////////////////// ...
- c_数据结构_图_邻接表
课程设计------邻接表 图的遍历实现课程设计:https://files.cnblogs.com/files/Vera-y/图的遍历_课程设计.zip #include<stdio.h> ...
- java数据结构_笔记(4)_图
图一.概念.图: 是一种复杂的非线性数据结构.图的二元组定义: 图 G 由两个集合 V 和 E 组成,记为:G=(V, E) 其中: V 是顶点的有穷非空集合,E 是 V 中顶点偶对(称为边)的有穷 ...
- 数据结构作业——图的存储及遍历(邻接矩阵、邻接表+DFS递归、非递归+BFS)
邻接矩阵存图 /* * @Author: WZY * @School: HPU * @Date: 2018-11-02 18:35:27 * @Last Modified by: WZY * @Las ...
- OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用_棋盘纹理贴图
读取bmp等图片格式中的像素还有难度,就先用这个棋盘图象素来弄了 代码打错一个就一直First-chance exception ,貌似还有一个要用q或者Q才能成功退出,不知道缺少哪句,我用窗口红叉退 ...
- 金牌分析师助力 鲁泰A图谋再造一个“鲁泰”?_财经_中国网
金牌分析师助力 鲁泰A图谋再造一个"鲁泰"?_财经_中国网 金牌分析师助力 鲁泰A图谋再造一个"鲁泰"?
- 聚焦设计交易与商业落地 DANG·DHUB设计师平台上线【图】_品牌资讯_服饰_太平洋时尚网
聚焦设计交易与商业落地 DANG·DHUB设计师平台上线[图]_品牌资讯_服饰_太平洋时尚网 聚焦设计交易与商业落地 DANG·DHUB设计师平台上线
- UML类图详解_关联关系_一对多
对于一对多的示例,可以想象一个账户可以多次申购.在申购的时候没有固定上限,下限为0,那么就可以使用容器类(container class)来搞,最常见的就是vector了. 下面我们来看一个“一对多” ...
- UML类图详解_关联关系_多对一
首先先来明确一个概念,即多重性.什么是多重性呢?多重性是指两个对象之间的链接数目,表示法是“下限...上限”,最小数据为零(0),最大数目为没有设限(*),如果仅标示一个数目级上下限相同. 实际在UM ...
随机推荐
- 如何调用DLL中的导出类
之前在网上一直查不到关于把类打包成dll文件的程序,今天自己写了个测试程序,供大家参考 一.生成类的dll文件 1.我是在vs2008上测试的,建立工程,在选择建立何种类型的工程的时候,勾上appli ...
- Nginx学习——简介及常用命令
Nginx简介 Nginx是什么 同Apache一样,都是一种WEB服务器 基于REST架构风格,以统一资源描述符(URI)或者统一资源定位符(URL)作为沟通依据,通过HTTP协议提供各种网络服务 ...
- <Linux>Linux基础学习(兄弟连版本)
1.Linux系统简介 1.1 Unix与Linux发展史 父子关系:Unix 是Linux的前身 1969年,肯丶汤姆森开发Unix系统(为了加快玩游戏的速度 - -,自己开发的系统) 1971年, ...
- Thread相关API
参考书籍:<java多线程核心编程技术> Thread相关API,这些API可以改变线程对象的状态 新建一个线程对象,调用start方法后,系统会为该线程分配CPU资源,此时该线程处于可运 ...
- thinkphp助手函数
tp3 C($name=null, $value=null,$default=null) 获取和设置配置参数 支持批量定义 load_config($file,$parse=CONF_PARSE) 加 ...
- Apache Tomcat下载、安装、环境变量配置以及项目部署
前言 针对在本地访问文件或资源出现的跨域问题,可以通过搭建本地服务器来解决,本篇随笔主要介绍通过搭建Apache Tomcat服务器来解决跨域.包括Apache Tomcat的下载.安装.环境变量的配 ...
- Tools: windbg 使用指南
windbg使用 符号表C:\Symbols; SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols 系统变量_NT_SYMBOL_PAT ...
- 欧拉定理、欧拉函数、a/b%c
怕忘了…… 欧拉函数 定义.证明.打表方法 欧拉定理 定义.证明 https://blog.csdn.net/zzkksunboy/article/details/73061013 剩余系.完系.简系 ...
- Laravel 开发环境搭建
本人使用的是Laravel5.5版本,需要PHP7支持,所以安装的环境是Apache2.php7.0.mysql5.7,系统为ubuntu14.04LTS(14以下的版本对php7支持不够),主要参考 ...
- 高危预警| SQL数据库成主要攻击对象,或引发新一轮大规模勒索
近日,阿里云安全团队发现,目前互联网上的服务器,SQL数据库仍然有不少处于直接暴露在公网的状态,且数量有上升趋势.黑客可以利用数据库存在的漏洞或弱口令直接获取数据,并植入勒索和挖矿病毒寻求牟利.阿里云 ...