数据结构-图-基本运算


文章目录

    • 定义
    • 存储结构
    • 结构体定义
    • 邻接表创建图
    • 输出图G
    • 销毁图
    • 邻接矩阵与邻接表的相互转化
    • 图的遍历
      • 深度优先搜索
      • 广度优先搜索
    • 判断图是否连通
    • 主函数调用测试
    • 结果
【数据结构-图-基本运算】
定义
图G由两个集合V和E组成,记为G=(V,E),其中V是顶点的有限集合,记为V(G), E是连接V中两个不同顶点(顶点对)的边的有限集合,记为E(G)
存储结构
  • 邻接矩阵
  • 邻接表
  • 十字链表
  • 邻接多重表
结构体定义
#include #include #include using namespace std; #define MAXV 100 #define INF 32767 typedef struct { int num; // 序号 int data; }VertexType; // 顶点类型typedef struct { int edges[MAXV][MAXV]; // 邻接矩阵数组 int n,e; // 顶点数,边数 VertexType vertex[MAXV]; // 顶点 }MatGraph; // 图的邻接表表示 typedef struct ANode {//边结点类型 int adjvex; //该边邻接点编号 struct ANode *nextarc; int weight; }ArcNode; typedef struct Vnode{// 头结点类型 VertexType data; // 顶点信息 int count; // 增加数据域:存放顶点入度 ArcNode *firstarc; }VNode; typedef struct { VNode adjlist[MAXV]; int n; int e; }AdjGraph; // 用一个头节点数组构造的图

邻接表创建图
// 用邻接表创建图 void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV], int n, int e) { int i,j; ArcNode* p; G = (AdjGraph*)malloc(sizeof(AdjGraph)); for(i=0; iadjlist[i].firstarc = NULL; for(i=0; i=0; j--) { if(A[i][j] !=0&&A[i][j]!=INF) { p = (ArcNode*)malloc(sizeof(ArcNode)); p->adjvex = j; p->weight = A[i][j]; p->nextarc = G->adjlist[i].firstarc; G->adjlist[i].firstarc = p; } } G->n = n , G->e = e; }

输出图G
//输出图G void DispAdj(AdjGraph *G) { int i; ArcNode *p; for(i=0; in; i++) { p = G->adjlist[i].firstarc; printf("%3d:",i); while(p!=NULL) { printf("%3d[%d]->",p->adjvex,p->weight); p = p->nextarc; } cout << "^\n"; } }

销毁图
// 销毁图 void DestroyAdj(AdjGraph *&G) { int i; ArcNode *pre, *p; for(i=0; in; i++) { pre = G->adjlist[i].firstarc; if(pre!=NULL) { p = pre->nextarc; while(p!=NULL) { free(pre); pre = p; p = p->nextarc; } free(pre); } } free(G); }

邻接矩阵与邻接表的相互转化
// 邻接矩阵转邻接表复杂度:O(n^2) void MatToList(MatGraph g, AdjGraph *&G) { int i,j; ArcNode *p; G = (AdjGraph*)malloc(sizeof(AdjGraph)); for(i=0; in; i++) G->adjlist[i].firstarc = NULL; for(i=0; i=0; j--) if(g.edges[i][j]!=0&&g.edges[i][j]!=INF) { p = (ArcNode*)malloc(sizeof(ArcNode)); p->adjvex = j; p->weight = g.edges[i][j]; p->nextarc = G->adjlist[i].firstarc; G->adjlist[i].firstarc = p; } G->n = g.n; G->e = g.e; } // 邻接表转邻接矩阵复杂度 O(n+e) void ListToMat(AdjGraph *G, MatGraph &g) { int i; ArcNode *p; for(i=0; in; i++) { p = G->adjlist[i].firstarc; while(p!=NULL) { g.edges[i][p->adjvex] = p->weight; p = p->nextarc; } } g.n = G->n; g.e = G->e; }

图的遍历 深度优先搜索
int visited[MAXV]={0}; // 深度优先搜索 DFSO(n+e) void DFS(AdjGraph *G,int v)// 遍历连通图 { ArcNode *p; visited[v] = 1; printf("%2d",v); p = G->adjlist[v].firstarc; while(p!=NULL) { if(visited[p->adjvex] == 0) DFS(G,p->adjvex); p = p->nextarc; } }void DFS1(AdjGraph *G)// 遍历非连通图 { for(int i=0; in; i++) if(visited[i]==0) DFS(G,i); }

广度优先搜索
// 广度优先搜索O(n^2) void BFS(AdjGraph *&G, int v)// 遍历连通图 { int w; ArcNode *p; int visited[MAXV] ={0}; visited[v] = 1; printf("%2d",v); deque de; de.push_back(v); while(!de.empty()) { w = *de.begin(); de.pop_front(); p = G->adjlist[w].firstarc; while(p!=NULL){ if(visited[p->adjvex] == 0) { printf("%2d",p->adjvex); visited[p->adjvex] = 1; de.push_back(p->adjvex); } p = p->nextarc; } } cout << endl; } void BFS1(AdjGraph *G)// 遍历非连通图 { for(int i=0; in; i++) if(visited[i]==0) BFS(G,i); }

判断图是否连通
bool Connect(AdjGraph *G) { int i; bool flag = true; for(int i=0; in; i++) visited[i] = 0; DFS(G,0); for(int i=0; in; i++) if(visited[i]==0) { flag = false; break; } return flag; }

主函数调用测试
int main() { int A[MAXV][MAXV] = { {0,28,INF,INF,INF,10,INF}, {26,0,16,INF,INF,INF,14}, {INF,16,0,12,INF,INF,INF}, {INF,INF,12,0,22,INF,18}, {INF,INF,INF,22,0,25,24}, {10,INF,INF,INF,25,0,INF}, {INF,14,INF,18,24,INF,0} }; AdjGraph *G; int n = 7,e = 18; CreateAdj(G,A,n,e); DispAdj(G); cout << "广度优先搜索产生的序列为: "; BFS(G,0); cout << "深度优先搜索产生的序列为: "; DFS(G,0); cout << endl; //cout << "图G是否连通: "; //printf(" %d",Connect(G)); DestroyAdj(G); return 0; }

结果 数据结构-图-基本运算
文章图片

P.S:马上考试了,我还在写博客,但我觉得这才是正确的复习方式,hahahha太真实了…

    推荐阅读