学习用,记录数据结构代码
8-13(其实是之前写的了)
图(graph)的邻接表、邻接矩阵实现以及各种操作
#include <bits/stdc++.h>
using namespace std;
#define MaxVertexNum 100
#define MaxNum 0xfffff
typedef char VertexType;
typedef int EdgeType;
struct MGraph //邻接矩阵表示法
{
VertexType Vex[MaxVertexNum]; //顶点集
EdgeType Edge[MaxVertexNum][MaxVertexNum]; //边集(弧集)
int vexnum,arcnum;
bool digraph; //1 = dirgraph ; 0 = undigraph
};
struct ArcNode //弧集
{
int adjvex; //弧的终点
struct ArcNode *next;
int value;
};
typedef struct Vnode //点集
{
VertexType data;
ArcNode *first;
}Vnode,AdjList[MaxVertexNum];
struct ALGraph //邻接表表示法
{
AdjList vertices;
int vernum,arcnum;
bool digraph;
};
//----------------------------------------以下为Graph的邻接矩阵实现的基本操作-----------------------------------------------------------
int Locate(const MGraph &mg,const VertexType &a)
{
int res =0;
while(mg.Vex[res]!=a) ++res;
if(res>=mg.vexnum) res = -1; //数组从0开始
return res;
}
bool Adjacent(const MGraph &mg,const VertexType &a,const VertexType &b)
{
int i = Locate(mg,a),j=Locate(mg,b);
if(a==-1||b==-1) return false;
return mg.Edge[i][j]!=0;
}
void Neighbors(const MGraph &mg,const VertexType &a)
{
int e = Locate(mg,a); if(e==-1) return;
string out1="(",out2=")"; if(mg.digraph) { out1="<"; out2=">"; }
for(int i=0;i<mg.vexnum;++i)
{
if(mg.Edge[i][e]!=0) cout<<out1+mg.Vex[i]+","+mg.Vex[e]+out2;
if(mg.Edge[e][i]!=0) cout<<out1+mg.Vex[e]+","+mg.Vex[i]+out2;
}
}
bool InsertVertex(MGraph &mg,const VertexType &a)
{
if(mg.vexnum>=MaxVertexNum) return false;
mg.Vex[mg.vexnum] = a;
memset(mg.Edge[mg.vexnum],0,(MaxVertexNum-1)*sizeof(EdgeType));
++mg.vexnum=mg.vexnum;
return true;
}
bool DeleteVertex(MGraph &mg,const VertexType &a)//这里不好让vernums--,因为他是数组,中间删了,nums--了,那是等于将最后一个元素给清空了啊。
{
int e = Locate (mg,a);
if(e==-1) return false;
mg.Vex[e] = NULL;
for(int i=0;i<mg.vexnum;++i)//!!没写图的弧的数目减少
{
mg.Edge[i][e] = 0;
mg.Edge[e][i] = 0;
}
return true;
}
bool AddEdge(MGraph &mg,const VertexType &a,const VertexType &b)
{
int i = Locate(mg,a),j = Locate(mg,b);
if(i==-1||j==-1||mg.Edge[i][j]!=0) return false;
if(!mg.digraph) mg.Edge[j][i]=1;
mg.Edge[i][j]=1;
++mg.arcnum;
return true;
}
bool RemoveEdge(MGraph &mg,const VertexType &a,const VertexType &b)
{
int i = Locate(mg,a),j = Locate(mg,b);
if(i==-1||j==-1) return false;
if(!mg.digraph) mg.Edge[j][i] = 0;
mg.Edge[i][j]==0;
--mg.arcnum;
return true;
}
int FirstNeighbor(const MGraph&mg,const VertexType &a)
{
int e = Locate(mg,a);
if(e==-1) return -1;
for(int i=0;i<mg.vexnum;++i) if(mg.Edge[e][i]!=0) return i;
return -1;
}
int NextNeighbor(const MGraph&mg,const VertexType &a,const VertexType &b)
{
int x = Locate(mg,a),y=Locate(mg,b);
if(x==-1||y==-1) return -1;
for(int i=y+1;i<mg.vexnum;++i) if(mg.Edge[x][i]!=0) return i;
return -1;
}
//----------------------------------------以上为Graph的邻接矩阵实现的基本操作-----------------------------------------------------------
//----------------------------------------以下为Graph的邻接表实现的基本操作-------------------------------------------------------------
int Locate(const ALGraph&alg,const VertexType &a)
{
for(int i=0;i<alg.vernum;++i) if(a==alg.vertices[i].data) return i;
return -1;
}
bool Adjacent(const ALGraph&alg,const VertexType &a,VertexType &b)
{
int i = Locate(alg,a),j = Locate(alg,b);
if(i==-1||j==-1) return false;
for(ArcNode *p = alg.vertices[i].first;p!=NULL;p=p->next) if(alg.vertices[p->adjvex].data==b) return true;
return false;
}
void Neighbors(const ALGraph&alg,const VertexType &a)
{
int e = Locate(alg,a); if(e==-1) return;
string out1="(",out2=")"; if(alg.digraph) { out1="<"; out2=">"; }
ArcNode *p = alg.vertices[e].first;
while(p!=NULL)
{
if(alg.digraph) cout<<out1+alg.vertices[p->adjvex].data+","+a+out2;
cout<<out1+a+","+alg.vertices[p->adjvex].data+out2;
p=p->next;
}
}
bool InsertVertex(ALGraph&alg,const VertexType &a)
{
if(alg.vernum>=MaxVertexNum) return false;
alg.vertices[alg.vernum].data=a;
alg.vertices[alg.vernum].first=NULL;
++alg.vernum;
return true;
}
bool DeleteVertex(ALGraph&alg,const VertexType &a)//这里不好让vernums--,因为他是数组,中间删了,nums--了,那是等于将最后一个元素给清空了啊。
{
int e = Locate(alg,a); if(e==-1) return false;
alg.vertices[e].data=NULL;
ArcNode*p = alg.vertices[e].first;
ArcNode*pre = NULL;
while(p!=NULL)
{
ArcNode *pt = p;
p=p->next;
delete pt;
--alg.arcnum;
}//删出度,即出去的弧
for(int i=0;i<alg.vernum;++i)//删入度,即进入的弧
{
p = alg.vertices[i].first;
while(p!=NULL)
{
if(alg.vertices[p->adjvex].data==a)
{
if(p==alg.vertices[i].first)
{
alg.vertices[i].first=p->next;
delete p;
p=alg.vertices[i].first;
--alg.arcnum;
}
else
{
pre->next=p->next;
delete p;
p=pre->next;
--alg.arcnum;
}
}
else
{
pre=p;
p=p->next;
}
}
}
return true;
}
bool AddEdge(ALGraph&alg,const VertexType &a,const VertexType &b)//头插法
{
int i=Locate(alg,a),j=Locate(alg,b); if(i==-1||j==-1) return false;
//Adjacent(alg,a,b);//为啥子不能用????重载了不是?==参数不同,adjacent函数的参数是 const alg。 add的alg 不是const
for(ArcNode *p = alg.vertices[i].first;p!=NULL;p=p->next) if(alg.vertices[p->adjvex].data==b) return false;
ArcNode *temp = new ArcNode;
temp->adjvex=j;
temp->next=alg.vertices[i].first;
alg.vertices[i].first=temp;
++alg.arcnum;
return true;
}
bool RemoveEdge(ALGraph&alg,const VertexType &a,const VertexType &b)//无向图得删两条边,这里只删了一条
{
int i=Locate(alg,a),j=Locate(alg,b); if(i==-1||j==-1) return false;
//Adjacent(alg,a,b);
ArcNode *pre=NULL;
for(ArcNode *p = alg.vertices[i].first;p!=NULL;p=p->next)
{
if(alg.vertices[p->adjvex].data==b)//遍历到了这条弧
{
if(p==alg.vertices[i].first)
{
alg.vertices[i].first=p->next;
delete p;
--alg.arcnum;
}
else
{
pre->next=p->next;
delete p;
p=pre->next;
--alg.arcnum;
}
return true;
}
pre=p;
}
return false;
}
int FirstNeighbor(const ALGraph&alg,const VertexType &a)
{
int e = Locate(alg,a); if(e==-1) return -1;
return alg.vertices[e].first->adjvex;
}
int NextNeighbor(const ALGraph&alg,const VertexType &a,const VertexType &b)
{
int i=Locate(alg,a),j=Locate(alg,b); if(i==-1||j==-1) return -1;
for(ArcNode *p=alg.vertices[i].first;p!=NULL;p=p->next)
{
if(p->adjvex==j)
{
if(p->next==NULL) return -1;
else return p->next->adjvex;
}
}
}
//----------------------------------------以上为Graph的邻接表实现的基本操作-------------------------------------------------------------
void visit(MGraph&mg,const VertexType &x){}
void visit(const MGraph&mg,const VertexType &x){}
void visit(ALGraph&alg,const VertexType &x){}
void visit(const ALGraph&alg,const VertexType &x){}
//----------------------------------------以下为Graph的邻接矩阵实现的遍历操作-----------------------------------------------------------
void BFS(const MGraph&mg,const int &x,bool visited[])
{
queue<int> qv; qv.push(x);
while(!qv.empty())
{
int i=qv.front(); qv.pop();
visit(mg,i); visited[i]=true;
for(int j=FirstNeighbor(mg,i);j>=0;j=NextNeighbor(mg,i,j))
if(mg.Edge[i][j]!=0&&!visited[j]) qv.push(j);//因为顶点是顺序存放的,所以删除空间不好删,就设置为NULL了。
}
}
void DFS(const MGraph&mg,const int &x,bool visited[])//不是干到底才访问,而是访问路径是干到底。(这鸡掰算法竟然是递归的,就这?)
{
visit(mg,x); visited[x]=true;
for(VertexType w=FirstNeighbor(mg,x);w>=0;w=NextNeighbor(mg,x,w))
if(!visited[w]&&mg.Vex[w]!=NULL) DFS(mg,w,visited);
}
void BFS_DFS_Travel(const MGraph&mg)//也可用来控制大的DFS
{
bool visited[MaxVertexNum];
memset(visited,0,sizeof(visited));
for(int i=0;i<mg.vexnum;++i)
{
if(!visited[i]&&mg.Vex[i]!=NULL) BFS(mg,i,visited);//DFS(mg,i,visited);
}
}
//----------------------------------------以上为Graph的邻接矩阵实现的遍历操作-----------------------------------------------------------
// (BFS+DFS)
//----------------------------------------以下为Graph的邻接表实现的遍历操作-------------------------------------------------------------
void BFS(const ALGraph&alg,const int &x,bool visited[])
{
queue<int>qv; qv.push(x);
while(!qv.empty())
{
int i=qv.front(); qv.pop();
visit(alg,i); visited[i]=true;
for(int j=FirstNeighbor(alg,i);j>=0;j=NextNeighbor(alg,i,j))
if(!visited[j]&&alg.vertices[j].data!=NULL) qv.push(j);//因为顶点是顺序存放的,所以删除空间不好删,就设置为NULL了。
}
}
void DFS(const ALGraph&alg,const int &x,bool visited[])//不是干到底才访问,而是访问路径是干到底。(这鸡掰算法竟然是递归的,就这?)
{
visit(alg,x); visited[x]=true;
for(VertexType w=FirstNeighbor(alg,x);w>=0;w=NextNeighbor(alg,x,w))
if(!visited[w]&&alg.vertices[w].data!=NULL) DFS(alg,w,visited);
}
void BFS_DFS_Travel(const ALGraph&alg)//也可用来控制大的DFS
{
bool visited[MaxVertexNum];
memset(visited,0,sizeof(visited));
for(int i=0;i<alg.vernum;++i)
{
if(!visited[i]&&alg.vertices[i].data!=NULL) BFS(alg,i,visited);//DFS(mg,i,visited);
}
}
//----------------------------------------以上为Graph的邻接表实现的遍历操作-------------------------------------------------------------
void BFS_Min_Distance(const MGraph&mg,const int &u)//最短路径。
{
int d[MaxVertexNum]; memset(d,MaxNum,sizeof(d));
bool visited[MaxNum]; memset(visited,0,sizeof(visited));
int i=u; d[i]=0;
queue<int> qi; qi.push(i);
while(!qi.empty())
{
i=qi.front(); qi.pop(); visited[i];
for(int w=FirstNeighbor(mg,i);w>=0;w=NextNeighbor(mg,i,w))
if(!visited[w])
{
d[w]=d[i]+1;
qi.push(w);
}
}
}
最后每天一句祝我上岸中山大学!!!