961数据结构总结--------图

1、结构
(1)邻接矩阵法

#define MaxVertexNum 100		//顶点数目最大值
typedef char VertexType;		//顶点数据类型
typedef int EdgeType;			//带权图中边上权值的数据类型
typedef struct{
	VertexType Vex[MaxVertexNum];					//顶点表
	EdgeType Edge[MaxVertexNum][MaxVertexNum];		//邻接矩阵,边表
	int vexnum,arcnum;			//图的当前顶点数和弧数
}MGraph;

(2)邻接表法

#define MaxVertexNum 100		//顶点数目最大值
typedef struct ArcNode{			//边表结点
	int adjvex;					//该弧所指向的顶点位置
	struct ArcNode *next;		//指向下一条弧的指针
	//InfoType info;			//网的边权值
}ArcNode;
typedef struct VNode{			//顶点表结点
	VertexType data;			//顶点信息
	ArcNode *first;				//指向第一条依附该结点的弧的指针
}VNode,AdjList[MaxVertexNum];
typedef struct{
	AdjList vertices;			//邻接表
	int vexnum,arcnum;			//图的顶点数和弧数
}ALGraph;

2、基本操作

Adjacent(G,x,y)				//判断图G是否存在边<x,y>
Neighbors(G,x)				//列出图G中与结点x邻接的边
InsertVertex(G,x)			//插入顶点x
DeletVertex(G,x)			//删除顶点x
AddEdge(G,x,y)				//若边<x,y>不存在,则添加
RemoveEdge(G,x,y)			//若边<x,y>不存在,则删除
FirstNeighbor(G,x)			//求顶点x的第一个邻接点,有则返回顶点号,否则返回-1
NextNeighbor(G,x,y)			//返回x的下一个顶点号(除y),若y是x的最后一个则返回-1
Get_edge_value(G,x,y)		//获得边(x,y)的权值
Set_edge_value(G,x,y,v)		//设置边(x,y)的权值

3、广度优先遍历(BFS)

bool visited[MAX_VERTEX_NUM]; 		//访问标记数组
void BFSTraverse(Graph G){ 			//对图G进行广度优先遍历
	for(i=0;i<G.vexnum;++i)
		visited[i]=FALSE; 			//访问标记数组初始化
	InitQueue(Q);					//初始化辅助队列Q
	for(i=0;i<G.vexnum;++i) 		//从0号顶点开始遍历
		if(!visited[i]) 			//对每个连通分量调用一次BFS
			BFS(G,i);				//vi未访问过,从vi开始BFS
}
void BFS (Graph G,int v){			//从顶点v出发,广度优先遍历图G
	visit(v); 						//访问初始顶点v
	visited[v]=TRUE; 				//对v做已访问标记
	Enqueue(Q,v); 					//顶点v入队列Q
	while(!isEmpty(Q))(
		DeQueue (Q,v); 				//顶点v出队列
		for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))//检测v所有邻接点
			if(!visited[w]){			//w为v的尚未访问的邻接顶点
				visit(w); 				//访问顶点w
				visited[w]=TRUE;		//对w做已访问标记
				EnQueue(Q,w); 			//顶点w入队列
		}//if
	}//while
}

4、深度优先遍历(DFS)

//递归
bool visited[MAX_VERTEX_NUM]; 		//访问标记数组
void DFSTraverse(Graph G){			//对图G进行深度优先遍历
	for(v=0;v<G.vexnum;++v)
		visited[v]=FALSE; 			//初始化已访问标记数据
	for(v=0;v<G.vexnum;++v) 		//本代码中是从v=0开始遍历
		if(!visited[v])
			DFS(G,v);
}
void DFS(Graph G,int v){			//从顶点v出发,深度优先遍历图G
	visit(v); 						//访问顶点v
	visited[v]=TRUE; 				//设已访问标记
	for(w=FirstNeighbor(G,v);w>=0;w=NextNeighor(G,v,w))
		if(!visited[w])				//w为u的尚未访问的邻接顶点
			DFS(G,w)}
//非递归
void DFS_Non_RC(AGraph& G,int v)(
//从顶点v开始进行深度优先搜索,一次遍历一个连通分量的所有顶点
	int w; 								//顶点序号
	InitStack(S); 						//初始化栈s
	for(i=0;i<G.vexnum;i++)
		visited[i]=FALSE; 				//初始化visited
	Push (S,v);   
	visited[v]=TRUE; 					//v入栈并置visited[v]
	while(!IsEmpty(S)){
		k=Pop(S)//栈中退出一个顶点
		visit(k)//先访问,再将其子结点入栈
		for(w=FirstNeighbor(G,k);w>=0;w=NextNeighor(G,k,w))	//k所有邻接点
			if(!visited[w]){			//未进过栈的顶点进栈
				Push(S,w);
				visited[w]=true; 		//作标记,以免再次入栈
			}//if
		}//while
}//DES_Non_RC

5、prim算法

int cost[MAX_V][MAX_V]; 	//cost [u][v]表示边e=(u,v)的衩值(不存在的情况下设为INF)
int mincost[MAX_V]; 		//从集合X出发的边到每个顶点的最小权值
bool used[MAX_V];			//顶点i是否包含在集合X中
int V; 						//顶点数

int prim(){
	for(int i=0; i<V ; ++i){
		mincost[i] = INF;
		used[i] = false;
	}
	mincost[0]=0int res =0while(true){
		int v=-1;					
		//从不属于X的顶点中选取从X到其权值最小的顶点
		for (int u=0; u< V; u++){
			if(!used[u] && (v ==-1 || mincost[u]< mincost[v]))	v=u;
		}
		
		if (v ==-1) break;
		used[v] = true;				// 把顶点v加入X
		res += mincost[v]; 			//把边的长度加到结果里

		for(int u=0;u< V; u++){
			mincost [u] = min(mincost[u], cost[v][u]);
		}
	}
	return res;
}

在这里插入图片描述

6、kruskal算法

struct edge{int u,v,cost;}bool comp(const edge& e1, const edge& e2){
	return e1.cost < e2.cost;
}

edge es[MAX_E];
int V, E; 				//顶点数和边数

int kruskal(){
	sort(es, es+ E, comp); 		//按照edge.cost的顺序从小到大排列
	init_union_find(V)//并查集的初始化
	int res=0;
	for(int i=0;i<E; i++){
		edge e = es[i];
		if (!same(e.u, e.v)){
			unite(e.u, e.v);
			res+= e.cost;
		}
	}
	return res;
}

7、Dijkstra算法

int cost[MAX_V][MAX_V]//cost[u][v]表示边e=(u,v)的权值(不存在这条边时设INF)
int d[MAX_V]//顶点s出发的最短距离
bool used[MAX_V]; 			//已经使用过的图
int V; 						//顶点数

//求从起点s出发到各个顶点的最短距离
void dijkstra(int s){
	fill(d, d+V, INF)fill(used, used+V, false);
	d[s]=0while(true){
		int v=-1;
		//从尚未使用过的顶点中选择一个距离最小的顶点
		for(int u=0; u< V; u++){
			if (!used[u] && (v ==-1 || d[u]<d[v]))	v=u;
		}
		
		if (v == -1) break;
		used[v] = true;
		
		for(int u=0 ; u<V ; u++){
			d[u] = min(d[u], d[v]+cost[v][u]);
		}
	}
}

8、Floyd算法

int i, j, k;
int d[MAXSIZE MAXSIZE), path[MAXSIZE][MAXSIZE]
//先把图的邻接矩阵复制到d
for( i=0; i<n; i++){
	for(=0; j<n; j++){
		d[i][j]=G.edge[i][j];
		path[i]=-1;
	}
}

for(k=0; k<n; k++){
	for(i=0; i<n; i++){
		for(j=0; j<n; j++){
			if(d[i][j]> d[i][k]+d[k][j])
				d[i][j]> d[i][k]+d[k][j];
				path[i][j]= k;
			}
		}
	}
}

9、拓扑排序

bool TopologicalSort (Graph G) {
	InitStack(S) ;				//初始化栈,存储入度为0的项点
	for(int i=0;i<G. vexnum;i++)
		if (indegree[i]==0)
			Push(S,i) ;			//将所有入度为0的顶点进栈
	int count=0;				//计数,记录当前已经输出的项点数
	
	while (!IsEmpty(S)) {		//栈不空,则存在入度为0的顶点
		Pop(S,i) ;				//栈顶元素出栈
		print [count++]=i;		//输出顶点i
		
		for(p=G.vertices[i].firstarc;p;p=p->nextarc) {
		//将所有i指向的顶点的入度减1,并且将入度减为0的顶点压入栈s
			v=p->adjvex;
			if(! (--indegree[v])
				Push(S,v); 		//入度为0, 则入栈
				
		}
	}//while
	
	if (count<G. vexnum)
		return false;			//排序失败,有向图中有回路
	else
		return true;			//拓扑排序成功
}

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值