目录
定义和基本术语
存储
数组(邻接矩阵)存储法
原理
顶点表Vexs + 邻接矩阵arcs
代码实现
#include<stdio.h>
#define MaxInt 32767
#define MVNum 100
typedef char VexType;
typedef int AcrType;
typedef struct{
VexType vexs[MVNum];
AcrType arcs[MVNum][MVNum];
int vexnum , arcnum;
}AMGraph;
int LocateVex(AMGraph G , int v){
for(int i = 0 ; i < G.vexnum ; i++){
if(v == G.vexs[i]) return i;
}
return -1;
}
void CreateUDN(AMGraph &G){
scanf("%d %d",&G.vexnum , &G.arcnum);
for(int i = 0 ; i < G.vexnum ; i++){
scanf("%c",&G.vexs[i]);
}
for(int i = 0 ; i < G.arcnum ; i++){
for(int j = 0 ; j < G.arcnum ; j++){
G.arcs[i][j] = MaxInt;
}
}
for(int i = 0 ; i < G.arcnum ; i++){
int v1 , v2 , w;
scanf("%d %d %d",&v1,&v2,w);
int m = LocateVex(G , v1);
int n = LocateVex(G , v2);
G.arcs[m][n] = w;
G.arcs[n][m] = w;
}
}
int main(){
return 0;
}
无向图:
初始化邻接矩阵时,w均为0;
构造邻接矩阵时,w为1。
有向网:
不要对称过去!单向!
优缺点
链表(邻接表)存储法
原理
代码实现
#include<stdio.h>
#define VerTexType int
#define MVNum 100
typedef struct ArcNode{
int adjvex;
struct ArcNode* nextarc;
}ArcNode;
typedef struct VNode{
VerTexType data;
ArcNode* firstarc;
}VNode , AdjList[MVNum];
typedef struct{
AdjList vertices;
int vexnum , arcnum;
}ALGraph;
int LocateVex(ALGraph G , int v){
for(int i = 0 ; i < G.vexnum ; i++){
if(v == G.vertices[i].data) return i;
}
return -1;
}
void CreateUDG(ALGraph &G){
scanf("%d %d",&G.vexnum,&G.arcnum);
for(int i = 0 ; i < G.vexnum ; i++){
scanf("%d",&G.vertices[i].data);
G.vertices[i].firstarc = NULL;
}
for(int i = 0 ; i <= G.arcnum ; i++){
int v1 , v2;
int m = LocateVex(G , v1);
int n = LocateVex(G , v2);
ArcNode* p1 = new ArcNode;
p1->adjvex = n;
p1->nextarc = G.vertices[m].firstarc;
G.vertices[m].firstarc = p1;
ArcNode* p2 = new ArcNode;
p2->adjvex = m;
p2->nextarc = G.vertices[n].firstarc;
G.vertices[n].firstarc = p2;
}
}
int main(){
return 0;
}
优缺点
前两者对比
十字链表(了解)
邻接多重表
遍历
DFS
原理
代码实现
#include<stdio.h>
#include<string.h>
#define MaxNum 100
typedef struct{
int vex[MaxNum];
int arc[MaxNum][MaxNum];
int vexnum , arcnum;
}AMGraph;
int LocateVex(AMGraph G , int v1){
for(int i = 0 ; i < G.vexnum ; i++){
if(G.vex[i] == v1) return i;
}
return -1;
}
void CreatUDN(AMGraph &G){
scanf("%d %d",G.vexnum , G.arcnum);
for(int i = 0 ; i < G.vexnum ; i++){
scanf("%d",G.vex[i]);
}
memset(G.arc , '\0' , sizeof G.arc);
for(int i = 0 ; i < G.arcnum ; i++){
int v1 , v2 , w;
scanf("%d %d %d",&v1,&v2,w);
int m = LocateVex(G , v1);
int n = LocateVex(G , v2);
G.arc[m][n] = w;
G.arc[n][m] = w;
}
}
bool visit[MaxNum];
void DFS(AMGraph G , int v){
visit[v] = true;
for(int j = 0 ; j < G.vexnum ; j++){
if(G.arc[v][j] != 0 && visit[j] != 1){
DFS(G , j);
}
}
}
int main(){
memset(visit , '\0' , sizeof visit);
return 0;
}
效率分析
附加应用(数(强)连通分量)
非联通图:随便选一个当开始结点把它DFS完,再选一个没visit过的结点,把它DFS完……(以此类推)
∴ 这也是一种数连通分量的方法
BFS
原理
代码实现
#include<stdio.h>
#include<string.h>
#define MAXSIZE 100
#define MVNum 100
typedef struct{
int* base;
int front;
int rear;
}SqQueue;
void InitQueue(SqQueue &Q){
Q.base = new int[MAXSIZE];
Q.front = Q.rear = 0;
}
void EnQueue(SqQueue &Q , int e){
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXSIZE;
}
void DeQueue(SqQueue &Q , int &e){
e = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXSIZE;
}
bool QueueEmpty(SqQueue Q){
if(Q.front == Q.rear) return true;
return false;
}
typedef struct ArcNode{
int adjvex;
struct ArcNode* nextarc;
}ArcNode;
typedef struct VNode{
int data;
ArcNode* firstarc;
}VNode , AdjList[MVNum];
typedef struct ALGraph{
AdjList vertices;
int vexnum , arcnum;
}ALGraph;
int LocateVex(ALGraph G , int v){
for(int i = 0 ; i < G.vexnum ; i++){
if(v == G.vertices[i].data) return i;
}
return -1;
}
void CreatUDG(ALGraph &G){
scanf("%d %d",G.vexnum,G.arcnum);
for(int i = 0 ; i < G.vexnum ; i++){
scanf("%d",G.vertices[i].data);
G.vertices[i].firstarc = NULL;
}
for(int i = 0 ; i < G.arcnum ; i++){
int v1 , v2;
scanf("%d %d",&v1,&v2);
int m = LocateVex(G , v1);
int n = LocateVex(G , v2);
ArcNode* p1 = new ArcNode;
p1->adjvex = m;
p1->nextarc = G.vertices[m].firstarc;
G.vertices[m].firstarc = p1;
ArcNode* p2 = new ArcNode;
p2->adjvex = n;
p2->nextarc = G.vertices[n].firstarc;
G.vertices[n].firstarc = p2;
}
}
int visit[MAXSIZE];
void BFS(ALGraph G , int v){
visit[v] = true;
SqQueue Q;
InitQueue(Q);
EnQueue(Q , v);
while(QueueEmpty(Q) != true){
int u;
DeQueue(Q , u);
for(int w = FirstAdjVex(G , u) ; w > 0 ; w = NextAdjVex(G , u , w)){
if(visit[w] == 0 ){
visit[w] = true;
EnQueue(Q , w);
}
}
}
}
int main(){
memset(visit , '\0' , sizeof visit);
return 0;
}
队列还有图都是小蒟蒻手敲的,语法没错,欢迎佬指正
ps:FirstAdjVex 和 NextAdjVex 还没写,2023年2月2日更新
(2023年3月12日评:可恶,忘记写了,so 写了一个代替这两个函数的,用了指针p)
void BFS (ALGraph G, int v) {
visited[v] = true;
queue<int> q1;
q1.push(v);
while (q1.empty() != false) {
int u = q1.front();
q1.pop();
ArcNode *p = G.vertices[u].firstarc;
for (int i = G.vertices[u].firstarc -> adjvex; i >= 0;) {
if (visited[i] == false) {
visited[i] = true;
q1.push(i);
}
p = p -> nextarc;
i = p -> adjvex;
}
}
}
效率分析
附加应用(数(强)连通分量)
非联通图:随便选一个当开始结点把它DFS完,再选一个没visit过的结点,把它DFS完……(以此类推)
∴ 这也是一种数连通分量的方法