邻接表做存储结构时,找邻接点所需的时间取决于顶点和边的数量,DFS,BFS时间复杂度为O(n+e)。
1、邻接表
2、邻接表 DFS:
从起点出发,走过的点要做标记,发现有没走过的点,就随意挑一个往前走,走不了就回退,此种路径搜索策略就称为“深度优先搜索”,简称“深搜”。其实称为“远度优先搜索”更容易理解些。因为这种策略能往前走一步就往前走一 步,总是试图走得更远。所谓远近(或深度),就是以距离起点的步数来衡量的。
算法思想:
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
3、邻接表 BFS:
代码
#include<iostream>
using namespace std;
typedef int vertextype; //顶点类型
typedef int edgetype; //边上的权值类型
#define max 100 //最大顶点数
class edgenode //边表结点
{
public:
int adjvex; //邻接点域,存放该顶点对应的下标
edgetype weight;//权值
edgenode * next;//链域,指向下一个邻接点
};
class vexnode //顶点表结点
{
public:
vertextype data; //顶点域,存放顶点信息
edgenode * firstnode;//边表头指针
};
class grapharrlist //“graph 图 arr 顶点数组 list 边链表”
{
public:
vexnode arrlist[max]; //一维数组存放顶点
int numvertexes, numedges;//顶点个数,边的个数
};
void createarrgarph(grapharrlist * G)
{
int i,j,k=0;
edgenode *e;
cout << "请输入顶点和边的个数" << endl;
cin >> G->numvertexes >> G->numedges;
cout << "输入顶点信息,建立顶点表" << endl;
for (i=0; i < G->numvertexes; i++) //建立顶点表
{
cin >> G->arrlist[i].data; //输入顶点信息
G->arrlist[i].firstnode=NULL; //并将边表置为空表
}
for (int k = 0; k < G->numedges; k++) //建立边表
{
cout << "输入边(Vi,Vj)上的顶点序号i,j" << endl;
cin >> i >> j;
e = new edgenode; //建立一个新节点
e->adjvex = j; //邻域序号为j
e->next = G->arrlist[i].firstnode; //头插法,将e指针指向当前顶点指向的结点
G->arrlist[i].firstnode = e; //当前结点的指针指向e
//*********无向图,一条边两个顶点,需要对i,j分别插入*********//
e = new edgenode; //建立一个新节点
e->adjvex = i; //邻域序号为i
e->next = G->arrlist[j].firstnode; //头插法,将e指针指向当前顶点指向的结点
G->arrlist[j].firstnode = e; //当前结点的指针指向e
}
}
bool visited[max]; //访问标志的数组
void DFS(grapharrlist G, int i) //深度优先递归算法,调用一次,遍历输出一个连通图
{
edgenode *p;
visited[i] = 1;
cout << G.arrlist[i].data<< " "; //打印顶点
p = G.arrlist[i].firstnode;
while (p)
{
if (!visited[p->adjvex])
DFS(G, p->adjvex); //对访问的邻接节点递归调用
p = p->next;
}
}
void DFStraverse(grapharrlist G) //深度遍历操作
{
for (int i = 0; i < G.numvertexes; i++)
visited[i] = 0; //初始化标志数组,顶点全为未访问
for (int i = 0; i < G.numvertexes; i++)
if (!visited[i]) //对未访问过的顶点递归调用。若是连通图,则调用一次
DFS(G, i);
}
bool visited1[max]; //标记数
void BFStraverse(grapharrlist G) //广度遍历算法
{
edgenode *p;
queue<vertextype> q;//队列
for (int i = 0; i < G.numvertexes; i++) //初始化标记数组
visited1[i] = 0;
for (int i = 0; i < G.numvertexes; i++) //对每一个顶点做循环
{
if (!visited1[i]) //如果顶点未访问就处理
{
visited1[i] = 1;
cout << G.arrlist[i].data << " ";
q.push(i); //将顶点入队
while (!q.empty())
{
i=q.front();
q.pop();
p = G.arrlist[i].firstnode; //找到当前顶点的边表头指针
while (p)
{
if (!visited1[p->adjvex]) //如果顶点未访问就处理
{
visited1[p->adjvex] = 1;
cout << G.arrlist[p->adjvex].data << " ";
q.push(p->adjvex);
}
p = p->next; //指针指向下一个邻接点
}
}
}
}
}
int main()
{
grapharrlist g;
createarrgarph(&g);
DFStraverse(g);
system("pause");
return 0;
}