我来CSDN了

图的基本操作

#include <iostream>
#include <assert.h>

using namespace std;

//采用邻接链表的方式
#define InfoTypde int
#define VertexType int
const int UNDIGRAPH = 0;
const int DIGRAPH	= 1;
const int MAX_VERTEX_NUM = 20;

typedef struct ArchNode
{
	int	vertexIndex;		//该弧指向顶点在图中顶点数组的索引,对应vertexs[20]的下标
	ArchNode *nextarc;		//指向下一条弧的指针
	InfoTypde info;			//比如弧的权重
}ArchNode;

typedef struct Vertex
{
	VertexType data;		//顶点信息
	ArchNode	*firstarc;	//指向第一条弧的指针
}Vertex;

//这样定义图有个坏处,一旦定义好,图中结点的个数就固定了!
typedef struct Graph
{
	Vertex *vertexs[MAX_VERTEX_NUM];	//存储顶点的数组,存放的是指向顶点的指针
	int vexNum;			//当前图中的定点数
	int arcNum;			//当前图中的弧的个数
	int kind;			//图的种类,有向图还是无向图
}Graph;

void createGraph(Graph *&G,int kind)
{
	if(G) G = NULL;
	G = (Graph *)malloc(sizeof(struct Graph));
	assert(NULL != G);
	for(int i = 0; i < MAX_VERTEX_NUM; ++i)
	{
		G->vertexs[i] = NULL;		//初始化指向顶点的指针为NULL
	}
	G->kind = kind;					//设置图的种类
	G->vexNum = 0;					//初始化图中顶点的个数
	G->arcNum = 0;					//初始化图中弧的个数
}

void destoryGraph(Graph *&G)
{
	ArchNode *cur,*next;
	//遍历顶点
	for(int i = 0; i < G->vexNum; ++i)
	{
		if(!G->vertexs[i])
			continue;
		next = G->vertexs[i]->firstarc;
		cur  = G->vertexs[i]->firstarc;
		while(cur)
		{
			next = cur->nextarc;
			free(cur);
			cur = next;
		}
		G->vertexs[i]->firstarc = NULL;
	}
	free(G);
	G = NULL;
}
//向图中增加结点
void addVertexToGraph(Graph *&G,VertexType data)
{
	if(G->vexNum >= MAX_VERTEX_NUM)
	{
		cout << "Too many vertex!" << endl;
		return ;
	}
	for(int i = 0; i < G->vexNum; ++i)
	{
		if(!G->vertexs[i])
			continue;
		if(G->vertexs[i]->data == data)
		{
			cout << "Already exists!" << endl;
			return;		//不允许重复			
		}
	}
	Vertex *pVeterx;
	pVeterx = (Vertex *)malloc(sizeof(struct Vertex));
	pVeterx->data = data;
	pVeterx->firstarc = NULL;
	G->vertexs[G->vexNum] = pVeterx;
	G->vexNum++;
}
//从图中删除一个结点
void delVertexFromGraph(Graph *&G,VertexType data)
{
	bool haveThisVertex = false;
	ArchNode *cur,*next,*temp,*pre;
	Vertex *anotherVertex;
	if(NULL == G)
		return;
	if(G->vexNum <= 0)
	{
		cout << "Have no vertex!" << endl;
		return ;
	}
	for(int i = 0; i < G->vexNum; ++i)
	{
		if(!G->vertexs[i])
			continue;
		if(G->vertexs[i]->data == data)
		{
			haveThisVertex = true;
			//以下循环用来删除顶点所指向的弧链表
			next = cur = G->vertexs[i]->firstarc;
			if(G->kind == DIGRAPH)	//如果是有向图
			{
				while(cur)
				{
					next = cur->nextarc;
					free(cur);
					G->arcNum --;	//弧的个数减一
					cur = next;
				}
				G->vertexs[i] = NULL;
			}
			else if(G->kind == UNDIGRAPH)	//如果是无向图,这个麻烦点
			{
				while(cur)
				{
					//找到待删除的弧的另一个结点,将它的弧链表中指向被删除结点的弧也删掉
					anotherVertex = G->vertexs[cur->vertexIndex];	//找到待删除弧对应的另一个结点
					temp = anotherVertex->firstarc,pre = NULL;
					while(temp)										//这个循环是为了删除另一个结点中保存弧信息
					{
						if(temp->vertexIndex == i)
						{
							//如果是首节点
							if(NULL == pre)	//或者if(NULL == pre)
							{
								anotherVertex->firstarc = temp->nextarc;
								free(temp);
							}
							else
							{
								pre->nextarc = temp->nextarc;
								free(temp);
							}
							break;	//找到即停止循环
						}
						pre = temp;
						temp = temp->nextarc;
					}
					next = cur->nextarc;
					free(cur);
					G->arcNum --;	//弧的个数减一
					cur = next;
				}
				G->vertexs[i] = NULL;
			}
			for(int j = i; j < G->vexNum - 1; ++j)
			{
				G->vertexs[j] = G->vertexs[j + 1];
			}
			G->vertexs[j] = NULL;	//
			G->vexNum-- ;			//结点的个数减一
			break;
		}
	}
	if(!haveThisVertex)
		cout << "没有该结点!" << endl;
}

//从图中查找一个值为指定值的结点的索引
int findVertexIndexInGraph(const Graph *G,VertexType data)
{
	if(NULL == G)
		return -1;
	for(int i = 0; i < G->vexNum; ++i)
	{
		if(!G->vertexs[i])
			continue;
		if(G->vertexs[i]->data == data)
		{
			return i;
			break;
		}
	}
	return -1;
}
//向图中增加一条弧
void addArchToGraph(Graph *&G,VertexType startData,VertexType endData,InfoTypde weight = 0)
{
	ArchNode *pArchNode,*cur;
	//先要找到start和end
	if(NULL == G)
		return;
	int startVertexIndex = findVertexIndexInGraph(G,startData);
	int endVertexIndex = findVertexIndexInGraph(G,endData);
	cur = G->vertexs[startVertexIndex]->firstarc;
	while(cur)
	{
		if(cur->vertexIndex == endVertexIndex)
		{
			cout << "Already have this arch!" << endl;
			return ;
		}
		cur = cur->nextarc;
	}
	if(startVertexIndex >= 0 && endVertexIndex >= 0)
	{
		if(G->kind == DIGRAPH)											//如果是有向图
		{
			pArchNode = (ArchNode *)malloc(sizeof(struct ArchNode));	//创建一个弧结点
			pArchNode->info = weight;
			pArchNode->nextarc = NULL;
			pArchNode->vertexIndex = endVertexIndex;
			cur = G->vertexs[startVertexIndex]->firstarc;
			if(NULL == cur)
			{
				G->vertexs[startVertexIndex]->firstarc = pArchNode;
			}
			else
			{
				while(cur->nextarc)
				{
					cur = cur->nextarc;
				}
				cur->nextarc = pArchNode;
			}
			G->arcNum ++;	//弧的条数加一
		}
		else if(G->kind == UNDIGRAPH)	//如果是无向图
		{
			pArchNode = (ArchNode *)malloc(sizeof(struct ArchNode));	//创建一个弧结点
			pArchNode->info = weight;
			pArchNode->nextarc = NULL;
			pArchNode->vertexIndex = endVertexIndex;
			cur = G->vertexs[startVertexIndex]->firstarc;
			if(NULL == cur)
			{
				G->vertexs[startVertexIndex]->firstarc = pArchNode;
			}
			else
			{
				while(cur->nextarc)
				{
					cur = cur->nextarc;
				}
				cur->nextarc = pArchNode;
			}
			pArchNode = (ArchNode *)malloc(sizeof(struct ArchNode));	//再创建一个弧结点
			pArchNode->info = weight;
			pArchNode->nextarc = NULL;
			pArchNode->vertexIndex = startVertexIndex;
			cur = G->vertexs[endVertexIndex]->firstarc;
			if(NULL == cur)
			{
				G->vertexs[endVertexIndex]->firstarc = pArchNode;
			}
			else
			{
				while(cur->nextarc)
				{
					cur = cur->nextarc;
				}
				cur->nextarc = pArchNode;
			}
			G->arcNum ++;	//弧的条数加一
		}
	}
	else
	{
		cout << "起点或终点不存在!" << endl;
		return ;
	}
}
//从图中删除一条弧
void delArchFromGraph(Graph *&G,VertexType startData,VertexType endData)
{
	ArchNode *cur,*pre;
	//先要找到start和end
	if(NULL == G)
		return;
	int startVertexIndex = findVertexIndexInGraph(G,startData);
	int endVertexIndex = findVertexIndexInGraph(G,endData);
	if(startVertexIndex >= 0 && endVertexIndex >= 0)
	{
		if(G->kind == DIGRAPH)
		{
			cur = G->vertexs[startVertexIndex]->firstarc,pre = NULL;
			while(cur)
			{
				if(cur->vertexIndex == endVertexIndex)
				{
					break;
				}
				pre = cur;
				cur = cur->nextarc;
			}
			if(NULL == cur)
			{
				cout << "这两个结点之间没有弧!" << endl;
				return ;
			}
			else
			{
				if(NULL == pre)	//是首节点
					G->vertexs[startVertexIndex]->firstarc = cur->nextarc;
				else
					pre->nextarc = cur->nextarc;
				free(cur);
				G->arcNum --;
			}
		}
		else if(G->kind == UNDIGRAPH)
		{
			cur = G->vertexs[startVertexIndex]->firstarc,pre = NULL;
			while(cur)
			{
				if(cur->vertexIndex == endVertexIndex)
				{
					break;
				}
				pre = cur;
				cur = cur->nextarc;
			}
			if(NULL == cur)
			{
				cout << "这两个结点之间没有弧!" << endl;
				return ;
			}
			else
			{
				if(NULL == pre)	//是首节点
					G->vertexs[startVertexIndex]->firstarc = cur->nextarc;
				else
					pre->nextarc = cur->nextarc;
				free(cur);
				//G->arcNum --;
			}

			cur = G->vertexs[endVertexIndex]->firstarc,pre = NULL;
			while(cur)
			{
				if(cur->vertexIndex == startVertexIndex)
				{
					break;
				}
				pre = cur;
				cur = cur->nextarc;
			}
			if(NULL == cur)
			{
				cout << "这两个结点之间没有弧!" << endl;
				return ;
			}
			else
			{
				if(NULL == pre)	//是首节点
					G->vertexs[endVertexIndex]->firstarc = cur->nextarc;
				else
					pre->nextarc = cur->nextarc;
				free(cur);
				G->arcNum --;
			}
		}
	}
	else
	{
		cout << "起点或终点不存在!" << endl;
		return ;
	}
}
//深度优先遍历
void DFSdetails(const Graph *G,int i,int satusArr[])
{
	ArchNode *cur;
	if(satusArr[i] == 1 )
		return;
	cout << G->vertexs[i]->data << " ";
	satusArr[i] = 1;
	cur = G->vertexs[i]->firstarc;
	while(cur)
	{
		DFSdetails(G,cur->vertexIndex,satusArr);
		cur = cur->nextarc;
	}
}

void DFS(const Graph *G)
{
	int satusArr[MAX_VERTEX_NUM] = {0};
	cout << "深度优先遍历:";
	if(NULL == G)
		return;
	for(int i = 0; i < G->vexNum; ++i)
	{
		DFSdetails(G,i,satusArr);
	}
	cout << endl;
}
//广度优先遍历 
/*
BFSdetails(const Graph *G,int i,int satusArr[])
{

	ArchNode *cur;
	int index[MAX_VERTEX_NUM];
	if(satusArr[i] == 1)
		return;
	cout << G->vertexs[i]->data << " ";
	satusArr[i] = 1;
	cur = G->vertexs[i]->firstarc;
	while(cur)
	{
		//将下标入队
	}
	while(队不空)
	{
		BFSdetails
	}
}
void BFS(const Graph *G)
{
	int satusArr[MAX_VERTEX_NUM] = {0};
	if(NULL == G)
		return;
	cout << "广度优先遍历:";
	for(int i = 0; i < G->vexNum; ++i)
	{
		BFSdetails(G,i,satusArr);
	}
	cout << endl;
}
*/
void prim(Graph *G,int arr[MAX_VERTEX_NUM][MAX_VERTEX_NUM],int vertexNums)
{
	int U[MAX_VERTEX_NUM] = {-1};//代表集合为空
	int V[MAX_VERTEX_NUM] = {0};
	if(vertexNums > MAX_VERTEX_NUM || NULL == arr)
		return;
	if(G)
		free(G);
}


利用 TensorFlow 训练自己的目标识别器。本文内容来自于我的毕业设计,基于 TensorFlow 1.15.0,其他 TensorFlow 版本运行可能存在问题。.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值