图——邻接表的DFS,BFS

6 篇文章 0 订阅
4 篇文章 0 订阅
邻接表做存储结构时,找邻接点所需的时间取决于顶点和边的数量,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;
}

在这里插入图片描述

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值