- 特点:多个对多个
- 顶点和边的集合:G=(V,E),V:顶点的有穷非空集合,E:边的有穷集合
- 完全图:任意两个点都有一条边相连
- 稀疏图:很少边或弧的图(e
- 稠密图:有较多边或弧
- 网:边或弧带权的图
- 邻接:有边或弧相连的两个顶点之间的关系
- 关联或依附:边或弧与顶点的关系
- 顶点的度:与顶点相关联的边的数目
- 路径:接续的边构成的顶点序列
- 路径长度:路径上边和弧的数目/权值的和
- 回路/环:第一个顶点和最后一个顶点相同的路径
- 简单回路:除了路径的起点和终点可以相同,其余顶点均不相同的路径
- 简单回路:除了路径的起点和终点相同,其余顶点均不相同的路径
- 连通图/强连通图(对有向图):对任意连个顶点都存在到达对方的路径
- 子图:类似子树
- 连通分量/强连通分量:
注意:删除任意一条边
- 图的存储结构:数组表示法,多重链表
- 数组表示法:
无向:如果存在i,j间的边或弧,1;否则,0;统计度,只看横或者竖
有向:横a 竖b,a→b,1或为权值;横b 竖a,b→a,0或无穷大;度,即看横也看竖
- 算法表示:
- 邻接表(链式):
表结点可以多一个类型用来存储权
对于有向:同理,只记出
- 算法表示:
-
十字链表:
逆邻接表和邻接表结合,针对有向图
增加一个指针域表示出度
-
邻接多重表:
针对无向表,
- 图的遍历:
思路:
DFS:
思路:
简而言之,一条路走到底,如果不行了,就回退,继续看有没有路可走
算法实现(对邻接矩阵):
算法实现(对邻接表):循环中变为链表指向下一个
BFS:
思路:
运用队列,步骤:队 0,入队 1,入队2,出队0,入队3,入队4,出队1,入队5.。。。。。
#include#include #include #define MAX_SIZE 6 #define OVERFLOW 1 // used to struct queue typedef struct traversal_ { int *data; int front; int rear; }Treversal,*treversal; //used to struct graph typedef struct graph_ { int **connect; int numbernodes; }Graph,*graph; treversal iniqueue(){ treversal resultqueue=(treversal)malloc(sizeof(Treversal)); resultqueue->data=(int *)malloc (sizeof(int)*MAX_SIZE); resultqueue->front=0; resultqueue->rear=0; return resultqueue; } int isqueueempty(treversal paraqueue){ if ((paraqueue->rear)%MAX_SIZE==paraqueue->front){ return 1; } return 0; } treversal enqueue(treversal paraqueue,int number){ if (paraqueue->front==(paraqueue->rear+1)%MAX_SIZE){ exit(OVERFLOW); } paraqueue->data[paraqueue->rear]=number; paraqueue->rear=(paraqueue->rear+1)%MAX_SIZE; return paraqueue; } int dedata(treversal paraqueue){ if (isqueueempty(paraqueue)){ exit(OVERFLOW); } return paraqueue->data[paraqueue->front]; } treversal dequeue(treversal paraqueue){ if (isqueueempty(paraqueue)){ exit(OVERFLOW); } paraqueue->front=(paraqueue->front+1)%MAX_SIZE; return paraqueue; } graph initgraph(int parasize,int **paradata){ graph resultgraph=(graph)malloc(sizeof(Graph)); resultgraph->connect=(int**)malloc(sizeof (int)*MAX_SIZE); resultgraph->numbernodes=parasize; for(int i=0;i connect[i]=(int *)malloc(sizeof(int)*MAX_SIZE); for (int q=0;q connect[i][q]=paradata[i][q]; } } return resultgraph; } void lenfitreversal(graph paragraph){ int isvis[paragraph->numbernodes]; for (int i=0;i numbernodes;i++){ isvis[i]=0; } treversal paraqueue=iniqueue(); paraqueue=enqueue(paraqueue,4); while (!isqueueempty(paraqueue)) { int var=dedata(paraqueue); paraqueue=dequeue(paraqueue); if (isvis[var]==0){ printf("%d ",var); isvis[var]=1; for (int q=0;q numbernodes;q++){ if (paragraph->connect[var][q]==1){ if (isvis[q]==0) paraqueue=enqueue(paraqueue,q); } } } } printf("rn"); } void depthitreversal(graph paragraph,int n, int *isvis){ printf("%d ",n); isvis[n]=1; for (int i=0;i numbernodes;i++){ if (isvis[i]==0 && paragraph->connect[n][i]==1){ depthitreversal(paragraph,i,isvis); } } } void testsample(){ int migraph[5][5]={ {0,1,0,1,0}, {1,0,1,0,1}, {0,1,0,1,1}, {1,0,1,0,1}, {0,1,0,1,0} }; int **tempptr; tempptr=(int **)malloc(sizeof(int*)*5); for (int i=0;i<5;i++){ tempptr[i]=(int*)malloc(sizeof (int)*5); for (int q=0;q<5;q++){ tempptr[i][q]=migraph[i][q]; } } graph l=initgraph(5,tempptr); printf("广度优先遍历:"); lenfitreversal(l); int iss[5]={0,0,0,0,0}; int *isvis=(int*)malloc(sizeof(int)*5); for (int q=0;q<5;q++){ isvis[q]=0; } printf("深度优先遍历:"); depthitreversal(l,4, isvis); } int main(){ testsample(); return 0; }
运行结果:



