深搜,广搜,图的遍历,基础(updating)

一、首先是图的存储和表示:

1.图的邻接矩阵表示:使用二维数组map[N][N]可表示图,map[u][v]的内容是一个标志。因为c语言中没有bool的类型,只有int的类型,所以在c中当值为1的时候,表示u和v两个点之间有边,当为0的时候表示两个点之间没有边。在c++中用bool表示,当为false的时候表示没有边,当为true的时候表示有边。

2.图的邻接表表示:用c++中的vector,是一个能够存放任意数据类型的动态数组,可以增加和压缩数据。具体函数为:

函数

表述

c.assign(beg,end)

c.assign(n,elem)

[beg; end)区间中的数据赋值给c

nelem的拷贝赋值给c

c.at(idx)

传回索引idx所指的数据,如果idx越界,抛出out_of_range

c.back()

传回最后一个数据,不检查这个数据是否存在。

c.begin()

传回迭代器重的可一个数据。

c.capacity()

返回容器中数据个数。

c.clear()

移除容器中所有数据。

c.empty()

判断容器是否为空。

c.end()

指向迭代器中的最后一个数据地址。

c.erase(pos)

c.erase(beg,end)

删除pos位置的数据,传回下一个数据的位置。

删除[beg,end)区间的数据,传回下一个数据的位置

c.front()

传回第一个数据。

get_allocator

使用构造函数返回一个拷贝。

c.insert(pos,elem)

c.insert(pos,n,elem)

c.insert(pos,beg,end)

pos位置插入一个elem拷贝,传回新数据位置。

pos位置插入nelem数据。无返回值。

pos位置插入在[beg,end)区间的数据。无返回值。

c.max_size()

返回容器中最大数据的数量。

c.pop_back()

删除最后一个数据。

c.push_back(elem)

在尾部加入一个数据。

c.rbegin()

传回一个逆向队列的第一个数据。

c.rend()

传回一个逆向队列的最后一个数据的下一个位置。

c.resize(num)

重新指定队列的长度。

c.reserve()

保留适当的容量。

c.size()

返回容器中实际数据的个数。

c1.swap(c2)

swap(c1,c2)

c1c2元素互换。

同上操作。

vector<Elem> c

vector <Elem> c1(c2)

vector <Elem> c(n)

vector <Elem> c(n, elem)

vector <Elem> c(beg,end)

c.~ vector <Elem>()

创建一个空的vector

复制一个vector

创建一个vector,含有n个数据,数据均已缺省构造产生

创建一个含有nelem拷贝的vector

创建一个以[beg;end)区间的vector

销毁所有数据,释放内存。

 

Vector操作

函数

描述

operator[]

返回容器中指定位置的一个引用。


//用vector方法创建邻接表式的数组
vector<int> v;
v.push_back(1);
v.push_back(1);
v.push_back(13);
v.push_back(14);
for(i = 0;i < v.size();i++)
{
	printf("%d",v[i];
}
二、图的遍历

图的遍历分为两种,深度优先(Depth-first-search)和广度优先(Breath-first-search)

1.深度优先(dfs)

dfs是从图中某一个结点出发,依次访问与之相通的没有被访问过的结点,直到图中与之相同的点都被访问到。若还有没有被访问到的点,则另选一个未被访问过的点,继续按照此过程深度遍历图,直到所有的结点都被访问到。

下面是深度优先的代码:

void dfs(int u)
{
	printf("%d",u);  //从未被访问的结点开始访问,并将其标记为已经被访问过 
	vis[u] = 1; 
	
	for(i= 1; i <= n;i++)  //依次深度优先访问与当前顶点邻接的但没有被访问过的点 
	if(vis[i] == 0 && map[u][i] == 1)
	dfs(i); 
} 

下面是dfs的应用

(1)判断图是否连通,计算连通分量的个数:

若一个图是连通的,有n个顶点,则从图的一个顶点出发进行深度优先遍历,所经过的顶点一定是n个。即对顶点为1-n的图,dfs(1)所访问的结点数一定是n个,用计数器ans作为所访问的次数,若ans为n,则一定是连通图。具体代码如下:

for(int i = 1;i <= n;i++)
if(vis[i] == 0)
{
	ans++;
	dfs(i);
} 

(2)欧拉(回)路问题:

欧拉路:从无向图的一个结点出发走一条道路,每条边恰好经过一次,这样的道路就会称为欧拉路。

欧拉回路:从图中的一个点开始,可以经过图中的每条边并回到最初的位置。

欧拉道路的判断方法:如果一个图是连通的,且该图最多有两个奇点(度数为奇数),则一定存在欧拉道路。

有欧拉回路所必须满足的条件是:

(1)有向图:保证图是连通图,而且每个节点的入度必须等于出度;

(2)无向图:保证图是连通图,且每个节点的度数必须为偶数(不能为0);

所以要判断欧拉回路和欧拉路,统计每个点的度,连通性可以用dfs判断。


你可能感兴趣的:(搜索)