1、图的两种构建方式
邻接矩阵(数组)和临接表(链表)
邻接矩阵:dfs 深度搜索:按照一条路一直走到头再找另一条路(),构造辅助数组visited[];递归算法
邻接表:bfs 广度搜索:看到分叉口就搜索,像二叉树的非递归算法层搜索一样,使用队列,构造辅助数组visited[];
图一 邻接矩阵
图二 邻接表
图三 邻接表说明
2、邻接矩阵代码
// 用临接矩阵表示
#define maxnum 100 // 最大可存储100个点
struct adGraph
{
char vexs[maxnum]; //顶点表
int arcs[maxnum][maxnum]; // 临接表
int vexnum; //当前点数
int arcnum; // 当前边数;
};
class Graph //图
{
public:
Graph(int vexnum,int arcnum)
{
creat_nodir(vexnum, arcnum);
initvisted();
}
void creat_nodir(int vexnum,int arcnum);
void creat_dir(int vexnum, int arcnum);
void dfs(char ch); //深度遍历查找ch
void initvisted(); //初始化visited
int findindex(char v);
int* visted = new int[this->g.vexnum]; //开辟辅助数组visited
adGraph g; //建立图g
};
void Graph::initvisted()
{
for (int i = 0; i < this->g.vexnum; i++)
{
visted[i] = 0;//初始化visited
}
}
//1输入总顶点数和总边数;将点的信息存入顶点表;初始化临接矩阵;构造邻接矩阵
void Graph::creat_nodir(int vexnum, int arcnum)//无向图
{
g.vexnum = vexnum; // 总顶点数 总边数
g.arcnum = arcnum;
char input;
for (int i = 0; i < g.vexnum; i++) //给顶点表赋值
{
cout << "给第" << i+1 << "个顶点赋值:";
cin >> input;
g.vexs[i] = input;
}
//初始化邻接矩阵
for (int i = 0; i < g.vexnum; i++)
{
for (int j = i; j < g.vexnum; j++)
{
g.arcs[i][j] = 0;
g.arcs[j][i] = g.arcs[i][j];
}
}
//构造邻接矩阵
int flag = 0;
for (int i = 0; i < g.vexnum; i++)
{
for (int j = i; j < g.vexnum; j++)
{
cout << "第" << i + 1 << "个顶点与第" << j + 1 << "个顶点有无连接?(有请输入1;无输入0)";
cin >> flag;
g.arcs[i][j] = flag;
g.arcs[j][i] = g.arcs[i][j];
}
}
}
void Graph::creat_dir(int vexnum, int arcnum) //有向图
{
g.vexnum = vexnum; // 总顶点数 总边数
g.arcnum = arcnum;
char input;
for (int i = 0; i < g.vexnum; i++) //给顶点表赋值
{
cout << "给第" << i + 1 << "个顶点赋值:";
cin >> input;
g.vexs[i] = input;
}
//初始化邻接矩阵
for (int i = 0; i < g.vexnum; i++)
{
for (int j = 0; j < g.vexnum; j++)
{
g.arcs[i][j] = 0;
}
}
//构造邻接矩阵
int flag = 0;
for (int i = 0; i < g.vexnum; i++)
{
for (int j = 0; j < g.vexnum; j++)
{
cout << "第" << i + 1 << "个顶点到第" << j + 1 << "个顶点有无连接?(有请输入1;无输入0)";
cin >> flag;
g.arcs[i][j] = flag;
}
}
}
int Graph::findindex(char v)
{
for (int i = 0; i < this->g.vexnum; i++)
{
if (g.vexs[i] == v)
{
return i;
}
}
return -1;
}
void Graph::dfs(char ch) // 深度搜索 ,循着一条路走到头
{
int i = findindex(ch); // 随便选择一个点开始找
cout << ch;
visted[i] = 1; //辅助数组visited置1,代表已经找到过
for (int w = 0; w < g.vexnum; w++)
{
if ((g.arcs[i][w] == 1) && (visted[w] == 0))
{
dfs(g.vexs[w]);
}
}
}
3、临接表代码
#include<queue>
#define maxnum 100
//顶点类型,临接类型
struct arcnode
{
int index;
arcnode* next;
};
struct vexnode
{
char data;
arcnode* first;
};
class Graph_link
{
public:
Graph_link(int vexnum, int arcnum)
{
creat_nodir(vexnum, arcnum);
initvisited();
}
void creat_nodir(int vexnum, int arcnum);
int find_index(char v);
void bfs(char ch);
void initvisited();
int vexnum; //当前顶点数目
int arcnum;
vexnode* vexarr = new vexnode[vexnum]; //开辟空间 数组形式
int* visited = new int[vexnum];
};
void Graph_link::initvisited()
{
for (int i = 0; i < vexnum; i++)
{
visited[i] = 0;
}
}
int Graph_link::find_index(char v)
{
for (int i = 0; i < this->vexnum; i++)
{
if (this->vexarr[i].data == v)
{
return i;
}
}
return -1;
}
//建立节点,根据边数一根一根建立
void Graph_link::creat_nodir(int vexnum, int arcnum) // 点数 边数
{
this->vexnum = vexnum;
this->arcnum = arcnum;
char input;
//构建顶点表
for (int i = 0; i < this->vexnum; i++)
{
cout << "第" << i + 1 << "个顶点的值为:";
cin >> input;
this->vexarr[i].data = input;
this->vexarr[i].first = NULL;
}
//构件边
char v1;
char v2;
for (int k = 0; k < this->arcnum; k++)
{
cout << "第" << k + 1 << "条边的两个端点:";
cin >> v1 >> v2;
int i = find_index(v1);
int j = find_index(v2);
arcnode* p = new arcnode;
p->index = j;
p->next = vexarr[i].first;
vexarr[i].first = p;
arcnode* q = new arcnode;
q->index = i;
q->next = vexarr[j].first;
vexarr[j].first = q;
}
}
void Graph_link::bfs(char ch) //广度优先遍历 无递归 使用队列思想
{
queue<int> q;
int i = find_index(ch); //ch 的位置
visited[i] = 1;
q.push(i);
while (!q.empty())
{
cout << vexarr[q.front()].data;
arcnode* p=vexarr[q.front()].first;
while (p != NULL)
{
int w = p->index;
if (visited[w] == 0)
{
q.push(w);
visited[w] = 1;
}
p = p->next;
}
q.pop();
}
}
int main()
{
Graph_link g(8,9);
g.bfs('a');
system("pause");
return 0;
}