存储方法
以下图为例,分别用邻接矩阵、邻接表和链式前向星建图。
邻接矩阵
- ( i , j ) (i,j) (i,j)表示 i → j i\to j i→j是否连通
A | B | C | D | |
---|---|---|---|---|
A | 0 | 1 | 1 | 0 |
B | 0 | 0 | 0 | 1 |
C | 0 | 0 | 0 | 1 |
D | 1 | 0 | 0 | 0 |
邻接表
假设边目录结点从 A ∼ D A\sim D A∼D分别为 0 ∼ 3 0\sim 3 0∼3
链式前向星
- 链式前向星是静态链表,结构类似于邻接表,故略。
邻接矩阵
存储结构
typedef struct{
int map[N][N];//邻接矩阵
char V[N];//顶点表
int n,e;//顶点数,边数
}Graph;
建图
void build(Graph &g){
cin>>g.n>>g.e;
for(int i=0;i<g.n;i++){
cin>>g.V[i];//输入顶点
}
for(int i=0;i<g.e;i++){
int x,y;
cin>>x>>y;
g.map[x][y]=1;//输入边
}
}
深度搜索
int visit[N];//访问数组
void DFS(Graph g,int k){
cout<<g.V[k]<<' ';
visit[k]=1;
for(int i=0;i<g.n;i++){
if(!visit[i]&&g.map[k][i]){
DFS(g,i);
}
}
for(int i=0;i<g.n;i++){
if(!visit[i]){
DFS(g,i);
}
}
}
广度搜索
int visit[N];//访问数组
void BFS(Graph g,int k){
queue<int> q;
q.push(k);//入队起始节点
visit[k]=1;
while(!q.empty()){//在队列里循环搜索分支直到队空
cout<<g.V[q.front()]<<' ';
for(int i=0;i<g.n;i++){
if(!visit[i]&&g.map[q.front()][i]){
q.push(i);
visit[i]=1;
}
}
q.pop();
}
for(int i=0;i<g.n;i++){//查找孤立结点
if(!visit[i]){
BFS(g,i);
}
}
}
示例
#include <iostream>
#include <queue>
using namespace std;
#define N 100
int visit[N];//访问数组
typedef struct{
int map[N][N];//邻接矩阵
char V[N];//顶点表
int n,e;//边数,顶点数
}Graph;
void build(Graph &g){
cin>>g.n>>g.e;
for(int i=0;i<g.n;i++){
cin>>g.V[i];//输入顶点
}
for(int i=0;i<g.e;i++){
int x,y;
cin>>x>>y;
g.map[x][y]=1;//输入边
}
}
void DFS(Graph g,int k){
cout<<g.V[k]<<' ';
visit[k]=1;
for(int i=0;i<g.n;i++){
if(!visit[i]&&g.map[k][i]){
DFS(g,i);
}
}
for(int i=0;i<g.n;i++){
if(!visit[i]){
DFS(g,i);
}
}
}
void BFS(Graph g,int k){
queue<int> q;
q.push(k);//入队起始节点
visit[k]=1;
while(!q.empty()){//在队列里循环搜索分支直到队空
cout<<g.V[q.front()]<<' ';
for(int i=0;i<g.n;i++){
if(!visit[i]&&g.map[q.front()][i]){
q.push(i);
visit[i]=1;
}
}
q.pop();
}
for(int i=0;i<g.n;i++){//查找孤立结点
if(!visit[i]){
BFS(g,i);
}
}
}
int main(){
Graph g;
build(g);
DFS(g,0);
//BFS(g,0);
return 0;
}
/*
4 5
a b c d
0 1
0 2
1 3
2 3
3 0
*/
邻接表
存储结构
typedef struct ArcNode{
int idx;
ArcNode *next=NULL;
}ArcNode;//边结点
typedef struct{
char data;
ArcNode *firstNode=NULL;
}VNode;//顶点结点
typedef struct{
VNode adjaV[N];//顶点的邻接表数组
int n,e;//点数,边数
}Graph;
建图
void build(Graph &g){
cin>>g.n>>g.e;
for(int i=0;i<g.n;i++){
cin>>g.adjaV[i].data;//输入顶点
}
for(int i=0;i<g.e;i++){
int x,y;
cin>>x>>y;//输入边
ArcNode *p=new ArcNode();
p->idx=y;
p->next=g.adjaV[x].firstNode;
g.adjaV[x].firstNode=p;
}
}
深度搜索
int visit[N];//访问数组
void DFS(Graph g,int k){
cout<<g.adjaV[k].data<<' ';
visit[k]=1;
for(ArcNode *p=g.adjaV[k].firstNode;p!=NULL;p=p->next){//递归查找
if(!visit[k]){
DFS(g,p->idx);
}
}
for(int i=0;i<g.n;i++){//查找孤立顶点
if(!visit[i]){
DFS(g,i);
}
}
}
广度搜索
int visit[N];//访问数组
void BFS(Graph g,int k){
queue<int> q;
q.push(k);//入队起始节点
visit[k]=1;
while(!q.empty()){//在队列里循环搜索分支直到队空
cout<<g.adjaV[q.front()].data<<' ';
for(ArcNode *p=g.adjaV[q.front()].firstNode;p!=NULL;p=p->next){
if(!visit[p->idx]){
q.push(p->idx);
visit[p->idx]=1;
}
}
q.pop();
}
for(int i=0;i<g.n;i++){//查找孤立顶点
if(!visit[i]){
BFS(g,i);
}
}
}
示例
#include <iostream>
#include <queue>
using namespace std;
#define N 100
int visit[N];//访问数组
typedef struct ArcNode{
int idx;
ArcNode *next=NULL;
}ArcNode;//边结点
typedef struct{
char data;
ArcNode *firstNode=NULL;
}VNode;//顶点结点
typedef struct{
VNode adjaV[N];//顶点的邻接表数组
int n,e;//点数,边数
}Graph;
void build(Graph &g){
cin>>g.n>>g.e;
for(int i=0;i<g.n;i++){
cin>>g.adjaV[i].data;//输入顶点
}
for(int i=0;i<g.e;i++){
int x,y;
cin>>x>>y;//输入边
ArcNode *p=new ArcNode();
p->idx=y;
p->next=g.adjaV[x].firstNode;
g.adjaV[x].firstNode=p;
}
}
void DFS(Graph g,int k){
cout<<g.adjaV[k].data<<' ';
visit[k]=1;
for(ArcNode *p=g.adjaV[k].firstNode;p!=NULL;p=p->next){//递归查找
if(!visit[k]){
DFS(g,p->idx);
}
}
for(int i=0;i<g.n;i++){//查找孤立顶点
if(!visit[i]){
DFS(g,i);
}
}
}
void BFS(Graph g,int k){
queue<int> q;
q.push(k);//入队起始节点
visit[k]=1;
while(!q.empty()){//在队列里循环搜索分支直到队空
cout<<g.adjaV[q.front()].data<<' ';
for(ArcNode *p=g.adjaV[q.front()].firstNode;p!=NULL;p=p->next){
if(!visit[p->idx]){
q.push(p->idx);
visit[p->idx]=1;
}
}
q.pop();
}
for(int i=0;i<g.n;i++){//查找孤立顶点
if(!visit[i]){
BFS(g,i);
}
}
}
int main(){
Graph g;
build(g);
DFS(g,0);
// BFS(g,0);
return 0;
}
/*
4 5
a b c d
0 1
0 2
1 3
2 3
3 0
*/
链式前向星
- 链式前向星就是静态链表实现的邻接表。
存储结构
int visit[N];//访问数组
char data[N];//顶点数据
int head[N];//邻接顶点的第一个顶点
int to[2*N],nex[2*N];//链接的顶点编号,链接的下一个to编号
int n,e;//顶点数,边数
建图
void build(){
memset(head,-1,sizeof(head));
memset(to,-1,sizeof(to));
memset(nex,-1,sizeof(nex));
cin>>n>>e;
for(int i=0;i<n;i++){
cin>>data[i];//输入顶点
}
for(int i=0;i<e;i++){
int x,y;
cin>>x>>y;
to[i]=y;
nex[i]=head[x];
head[x]=i;
}
}
深度搜索
int visit[N];//访问数组
void DFS(int k){
cout<<data[k]<<' ';
visit[k]=1;
for(int i=head[k];i!=-1;i=nex[i]){//递归查找
if(!visit[to[i]]){
DFS(to[i]);
}
}
for(int i=head[k];i!=-1;i=nex[i]){//查找孤立顶点
if(!visit[to[i]]){
DFS(to[i]);
}
}
}
广度搜索
int visit[N];//访问数组
void BFS(int k){
queue<int> q;
q.push(k);//入队起始节点
visit[k]=1;
while(!q.empty()){//在队列里循环搜索分支直到队空
cout<<data[q.front()]<<' ';
for(int i=head[q.front()];i!=-1;i=nex[i]){
if(!visit[to[i]]){
q.push(to[i]);
visit[to[i]]=1;
}
}
q.pop();
}
for(int i=head[k];i!=-1;i=nex[i]){//查找孤立结点
if(!visit[to[i]]){
BFS(to[i]);
}
}
}
示例
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define N 100
int visit[N];//访问数组
char data[N];//顶点数据
int head[N];//邻接顶点的第一个顶点
int to[2*N],nex[2*N];//链接的顶点编号,链接的下一个to编号
int n,e;//顶点数,边数
void build(){
memset(head,-1,sizeof(head));
memset(to,-1,sizeof(to));
memset(nex,-1,sizeof(nex));
cin>>n>>e;
for(int i=0;i<n;i++){
cin>>data[i];//输入顶点
}
for(int i=0;i<e;i++){
int x,y;
cin>>x>>y;
to[i]=y;
nex[i]=head[x];
head[x]=i;
}
}
void DFS(int k){
cout<<data[k]<<' ';
visit[k]=1;
for(int i=head[k];i!=-1;i=nex[i]){//递归查找
if(!visit[to[i]]){
DFS(to[i]);
}
}
for(int i=head[k];i!=-1;i=nex[i]){//查找孤立顶点
if(!visit[to[i]]){
DFS(to[i]);
}
}
}
void BFS(int k){
queue<int> q;
q.push(k);//入队起始节点
visit[k]=1;
while(!q.empty()){//在队列里循环搜索分支直到队空
cout<<data[q.front()]<<' ';
for(int i=head[q.front()];i!=-1;i=nex[i]){
if(!visit[to[i]]){
q.push(to[i]);
visit[to[i]]=1;
}
}
q.pop();
}
for(int i=head[k];i!=-1;i=nex[i]){//查找孤立结点
if(!visit[to[i]]){
BFS(to[i]);
}
}
}
int main(){
build();
DFS(0);
// BFS(0);
return 0;
}
/*
4 5
a b c d
0 1
0 2
1 3
2 3
3 0
*/
版权声明
- 本文档归cout0所有,仅供学习使用,未经允许,不得转载。