图没有顺序结构
邻接矩阵-用于边集合较密集的情况
图结点的定义#include边的定义#include #include #include #define ERROR -1 #define MaxVertexNum 100 //最大顶点数设为100 #define INFINITY 65535 typedef int Vertex; //用顶点下标表示顶点 typedef int WeightType;//边的权值设为整型 typedef char DataType;//顶点存储的数据类型设为字符型 typedef int ElementType; typedef int Position; typedef struct GNode *PtrToGNode; struct GNode { int Nv; //顶点数 int Ne; //边数 WeightType G[MaxVertexNum][MaxVertexNum]; //邻接矩阵 DataType Data[MaxVertexNum]; //存顶点的数据 int Visited[MaxVertexNum]; }; typedef PtrToGNode MGraph;
typedef struct ENode *PtrToENode; struct ENode { Vertex V1,V2; //有向边邻接矩阵的创建WeightType Weight; //权重 }; typedef PtrToENode Edge;
//初始化一个有VertexNum个顶点但没有边的图 MGraph CreateGraph(int VertexNum) { Vertex V,W; MGraph Graph; Graph = (MGraph)malloc(sizeof(struct GNode)); Graph->Nv = VertexNum; Graph->Ne = 0; for(V=0; V深度优先遍历O()Nv; V++) for(W=0; W Nv; W++) Graph->G[V][W] = INFINITY; return Graph; } //边的插入 void InsertEdge(MGraph Graph, Edge E) { Graph->G[E->V2][E->V1] = E->Weight; Graph->G[E->V1][E->V2] = E->Weight; //无向图 } //读入图的信息存入邻接矩阵 MGraph BuildGraph() { MGraph Graph; Edge E; Vertex V; int Nv,i; printf("请输入顶点个数:"); scanf("%d",&Nv); //读入顶点个数 Graph = CreateGraph(Nv); //初始化图的Ne=0 printf("请输入边数:"); scanf("%d",&(Graph->Ne)); //读入边数 if(Graph->Ne!=0) { E = (Edge)malloc(sizeof(struct ENode)); //建立边结点 for(i = 0; i Ne; i++) { printf("初始化边,请输入:“边的起点,终点和权重(有向图)”"); scanf("%d %d %d",&E->V1,&E->V2,&E->Weight); //读入边,格式为起点 终点 权重 InsertEdge(Graph, E); ///插入邻接矩阵 } } //如果顶点有数据的话读入数据 for(V = 0; V Nv; V++) scanf("%c",&(Graph->Data[V])); return Graph; }
- 树的先序遍历的推广
void Visit(Vertex V) { printf("正在访问顶点%dn",V); } void DFS(MGraph Graph, Vertex V) { Vertex W; Visit(V); //首先访问当前结点 Graph->Visited[V] = 1; for (W = 0; W < Graph->Nv; W++) //W的每个邻接点 if(!Graph->Visited[W] && Graph->G[V][W]广度优先遍历——队列实现(队列 *** 作见前) - 树的层序遍历的推广
- O()
//队列的定义 struct QNode { ElementType *Data; Position Front, Rear; int MaxSize; }; typedef struct QNode *Queue; bool IsEdge(MGraph Graph, Vertex V, Vertex W) { return Graph->G[V][W]Visited[S] = 1; //标记S已访问 AddQ(Q,S); //S入队列 while(!IsEmpty(Q)) { V = DeleteQ(Q); //d出V for(W = 0; W < Graph->Nv; W++) //对图中的每个顶点 if(IsEdge(Graph,V,W) && !Graph->Visited[W]) { //若W是V的邻接点且未访问过 Visit(W); //访问顶点W Graph->Visited[W] = 1; //标记顶点W已访问 AddQ(Q,W); //W入队列 } } }
邻接表 数据结构定义//邻接点结点的定义 typedef struct AdjVNode *PtrToAdjVNode; struct AdjVNode { Vertex AdjV; //邻接点下标 WeightType Weight; //边权重 PtrToAdjVNode Next; //不要忘记Next域 }; //顶点表头结点的定义(一维数组) typedef struct VNode { PtrToAdjVNode FirstEdge; //边表头指针,指向第一个邻接点 DataType Data; //存顶点的数据 }AdjList[MaxVertexNum]; //图的定义 typedef struct GNode *PtrToGNode; struct GNode { int Nv; //顶点数 int Ne; //边数 AdjList G; //邻接表表头 int Visited[MaxVertexNum]; }; typedef PtrToGNode LGraph; //边的定义 typedef struct ENode *PtrToENode; struct ENode { Vertex V1,V2; //有向边邻接表的创建WeightType Weight; //权重 }; typedef PtrToENode Edge; //初始化一个有VertexNum个顶点但没有边的图 LGraph CreateGraph(int VertexNum) { Vertex V; LGraph Graph; Graph = (LGraph)malloc(sizeof(struct GNode)); Graph->Nv = VertexNum; Graph->Ne = 0; for(V=0; V深度优先遍历O(N+E)Nv; V++) Graph->G[V].FirstEdge = NULL; return Graph; } //插入边 void InsertEdge(LGraph Graph, Edge E) { PtrToAdjVNode NewNode1,NewNode2; NewNode1 = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); NewNode1->AdjV = E->V2; NewNode1->Weight = E->Weight; NewNode1->Next = Graph->G[E->V1].FirstEdge; Graph->G[E->V1].FirstEdge = NewNode1; //无向图 NewNode2 = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); NewNode2->AdjV = E->V1; NewNode2->Weight = E->Weight; NewNode2->Next = Graph->G[E->V1].FirstEdge; Graph->G[E->V2].FirstEdge = NewNode2; } //图的建立 LGraph BuildGraph() { LGraph Graph; Edge E; Vertex V; int Nv,i; printf("请输入顶点个数:"); scanf("%d",&Nv); //读入顶点个数 Graph = CreateGraph(Nv); //初始化图的Ne=0 printf("请输入边数:"); scanf("%d",&(Graph->Ne)); //读入边数 if(Graph->Ne!=0) { E = (Edge)malloc(sizeof(struct ENode)); //建立边结点 for(i = 0; i Ne; i++) { printf("初始化边,请输入:“边的起点,终点和权重(有向图)”"); scanf("%d %d %d",&E->V1,&E->V2,&E->Weight); //读入边,格式为起点 终点 权重 InsertEdge(Graph, E); ///插入邻接矩阵 } } //如果顶点有数据的话读入数据 for(V = 0; V Nv; V++) scanf("%c",&(Graph->G[V].Data)); return Graph; } void Visit(Vertex V) { printf("正在访问顶点%dn",V); } void DFS(LGraph Graph, Vertex V) { PtrToAdjVNode W; Visit(V); //首先访问当前结点 Graph->Visited[V] = 1; for (W = Graph->G[V].FirstEdge; W; W = W->Next) //递归访问W每个邻接点 if(!Graph->Visited[W->AdjV]) DFS(Graph, W->AdjV); }广度优先遍历——队列实现- O(N+E)
//队列中结点的定义 struct Node{ ElementType Data; PtrTonode Next; }; typedef PtrTonode Position; void BFS(LGraph Graph, Vertex S) { Queue Q; Vertex V; PtrToAdjVNode W; Q = CreateQueue(100); Visit(S); //访问顶点S Graph->Visited[S] = 1; //标记S已访问 AddQ(Q,S); //S入队列 while(!IsEmpty(Q)) { V = DeleteQ(Q); //d出V for(W = Graph->G[V].FirstEdge; W; W = W->Next) //对图中的每个顶点W if(!Graph->Visited[W->AdjV]) { //若W未访问过 Visit(W->AdjV); //访问顶点W Graph->Visited[W->AdjV] = 1; //标记顶点W已访问 AddQ(Q,W->AdjV); //W入队列 } } }对以上 *** 作的测试
int main(void) { MGraph Graph; Graph = BuildGraph(); Vertex V = 0; for(V = 0; VNv; V++) Graph->Visited[V] = 0; DFS(Graph, V); BFS(Graph, V); return 0; } 欢迎分享,转载请注明来源:内存溢出
评论列表(0条)