1,038
社区成员




这是我参加“朝闻道”知识分享大赛的第五十五篇文章。
//边结构
typedef struct ArcNode{
int adjvex; //该边所指向的顶点的位置
struct ArcNode *nextarc; //指向下一条边
int weight; //边上的权值
}ArcNode;
//顶点结构
typedef struct VNode{
char data;
bool visited;
ArcNode *firstArc; //指向第一个依附于该顶点的边
}VNode,AdjList; //顶点的邻接表类型
//图结构
typedef struct AlGraph{
AdjList vertices[V_MAX]; //顶点
int vexnum,arcnum; //顶点数目和边的数目
}AlGraph;
//创建无向图
void CreateGraph(AlGraph &G){
cout<<"输入顶点数量和边的数量:"<<endl;
cin>>G.vexnum>>G.arcnum; //输入顶点数量和边的数量
//处理顶点数据
cout<<"输入顶点数据"<<endl;
for(int i=0;i<G.vexnum;i++){
cin>>G.vertices[i].data; //输入顶点数据
G.vertices[i].firstArc=nullptr; //将指向第一个依附于顶点的边的指针置为空
G.vertices[i].visited=false; //还未被访问
}
//处理边的数据
for(int j=0;j<G.arcnum;j++){
char v1,v2;
cout<<"输入边两头的顶点:"<<endl;
cin>>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;
}
}
//深度遍历算法DFS,v表示的就是出发的顶点的位置为v
// !!!AlGraph用引用是为了真正改变其中顶点数组vertices中visited的值
void DFS_AL(AlGraph &G,int v){
cout<<G.vertices[v].data; //输出顶点的数据
G.vertices[v].visited=true; //将已经访问过的节点置为true
ArcNode *p=G.vertices[v].firstArc;
while(p!=nullptr){
int w=p->adjvex; //p不为空就跳到它指向节点的下标
if(!G.vertices[w].visited){ //判断其是否被访问过了,没有访问则进行递归
DFS_AL(G,w);
}
p=p->nextarc;
}
}
广度优先算法是需要借助队列的,它和层次遍历很像,都是通过在队列中弹出来的元素去找到该访问并且要入队的元素。
//广度优先算法
bool visited_BFS[V_MAX]={false}; //判断在广度优先算法中该顶点是否被标记
void BFS_AL(AlGraph G,int v){
cout<<G.vertices[v].data; //先访问初始节点
visited_BFS[v]=true; //将访问过的节点标记为true
LQueue Q;
InitQueue(&Q);
LqPush(&Q,v);
while(!isEmpty(Q)){
int u=LqPop(&Q); //接收队头元素
ArcNode *p=G.vertices[u].firstArc;
int w=G.vertices[u].firstArc->adjvex;
while(w>=0){
if(!visited_BFS[w]){
cout<<G.vertices[w].data;
visited_BFS[w]=true;
LqPush(&Q,w);
}
p=p->nextarc;
if(p!=nullptr){
w=p->adjvex;
}else{
break;
}
}
}
}