精华内容
下载资源
问答
  • OpenCV中图像处理最关键最基础部分就是像素点的遍历,在OpenCV中提供了丰富函数及其方法来进行像素的遍历,在不少资料上也基本统一,无非是基于c语言指针的遍历,基于c++迭代器遍历以及at方法遍历。...

            OpenCV中的图像处理最关键最基础的部分就是像素点的遍历,在OpenCV中提供了丰富的函数及其方法来进行像素的遍历,在不少的资料上也基本统一,无非是基于c语言的指针的遍历,基于c++的迭代器遍历以及at方法遍历。下面分别列出三种方法代码来记录一下这三种方法,代码和方法参考了《Opencv3编程学习》和《Opencv2计算机视觉编程》两本书,并采用c++接口风格。本个例子是对三通道彩色图像做颜色压缩处理。

    1、指针遍历方法

    void colorReduce1(Mat inputImg,Mat outputImg,int div)
    {
    	outputImg = inputImg.clone();
    	int rows = outputImg.rows;
    	int cols = outputImg.cols;
    	int colNum = cols*outputImg.channels();
    	for(int i = 0;i < rows;i++)
    	{
    		uchar *data = outputImg.ptr<uchar>(i);
    		for (int j = 0;j < colNum;j++)
    		{
    			data[j] = data[j]/div*div+div/2;
    		}
    	}
    }
    这种方法的基本思路是,图像矩阵在内存中是一段连续的内存,因此可以用指针偏移的方法来访问每一个像素的每一个通道。这里最重要的一句话就是访问到矩阵每一行的首地址,也就是下面这句话。
    uchar *data = outputImg.ptr<uchar>(i);

    还有另外一种c风格的指针遍历法,那一种方法比上述方法更加不直观,但是原理和上述代码完全相同。

    2、迭代器法

    void colorReduce2(Mat inputImg,Mat outputImg,int div)
    {
    	outputImg = inputImg;
    	int rows = inputImg.rows;
    	int cols = inputImg.cols;
    	Mat_<Vec3b>::iterator it = outputImg.begin<Vec3b>();
    	Mat_<Vec3b>::iterator itend = outputImg.end<Vec3b>();
    	for (;it!=itend;it++)
    	{
    		(*it)[0] = (*it)[0]/div*div+div/2;
    		(*it)[1] = (*it)[1]/div*div+div/2;
    		(*it)[2] = (*it)[2]/div*div+div/2;
    	}
    }
    这种方法利用了c++的迭代器,最大的优势就是不会有数组越界的情况,安全性有保证,而且比较直观。不足是速度较为指针较慢。

    3、at方法

    void colorReduce3(Mat inputImg,Mat outputImg,int div)
    {
    	outputImg = inputImg;
    	int rows = inputImg.rows;
    	int cols = inputImg.cols;
    	for (int i = 0;i < rows;i++)
    	{
    		for (int j = 0;j < cols;j++)
    		{
    			outputImg.at<Vec3b>(i,j)[0] = outputImg.at<Vec3b>(i,j)[0]/div*div+div/2;
    			outputImg.at<Vec3b>(i,j)[1] = outputImg.at<Vec3b>(i,j)[1]/div*div+div/2;
    			outputImg.at<Vec3b>(i,j)[2] = outputImg.at<Vec3b>(i,j)[2]/div*div+div/2;
    		}
    	}
    }

    同样是直观的写法,但是速度比迭代器更慢。


    展开全文
  • 本文基本上把常用的遍历方法都讲解了。在图像处理时经常会用到遍历图像像素点方式,同样是遍历图像像素点,共有很多中方法可以做到;在这些方法中,有相对高效,也有低效;不同场景使用不同方法。 数据格式...

    本文基本上把常用的遍历方法都讲解了。在图像处理时经常会用到遍历图像像素点的方式,同样是遍历图像像素点,共有很多中方法可以做到;在这些方法中,有相对高效的,也有低效的;不同场景使用不同方法。
    数据格式千万不要搞错:
    uchar对应的是CV_8U,char对应的是CV_8S,int对应的是CV_32S,float对应的是CV_32F,double对应的是CV_64F。

    1、遍历图像像素方法一:通过at(i,j)坐标指针
    说明:就是把图像看成二维矩阵,at(i,j)索引坐标位置,单通道直接得到坐标位置对应的像素值,三通道就这个位置代表了像素值的一维数组;
     

    //遍历图像像素方法一:通过at<type>(i,j)坐标指针
    	for (int i = 0; i < src.rows; i++)
    	{
    		for (int j = 0; j < src.cols; j++)
    		{
    			if (src.channels() == 1)
    			{
    				dst.at<uchar>(i, j) = src.at<uchar>(i, j) + 100;
    			}
    			else if (src.channels() ==3)
    			{
    				dst1.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0] + 100;
    				dst1.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1] + 100;
    				dst1.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2] + 100;
    			}
    		}
    	}
    

    2、遍历图像像素方法二:data遍历索引法
    说明:data方法就是对于单通道就是把灰度图像看成二维数组,数组的排列先行后列,一行索引后进入此行的列,每个位置就是一个像素值;三通道彩色图像,就是在灰度图像的基础,索引的位置不是单个值而是一个一维数组。切记data是数据真正存储位置的指针
     

    //遍历图像像素方法二:data遍历索引法
    	for (int i = 0; i < src.rows; i++)
    	{
    		for (int j = 0; j < src.cols; j++)
    		{
    			if (src.channels() == 1)
    			{
    				//图像数组是逐行逐列顺序排列的,也就是第一行,全列,第二行全列的走
    				int indexs = i * src.cols + j;
    				dst.data[indexs] = src.data[indexs] + 100;
    			}
    			else if (src.channels() == 3)
    			{
    				int indexs = i * src.cols + j;
    				//在彩色图像中,每个indexs又是三个通过的数组
    				dst1.data[3 * indexs + 0] = src.data[3 * indexs + 0] + 100;
    				dst1.data[3 * indexs + 1] = src.data[3 * indexs + 1] + 100;
    				dst1.data[3 * indexs + 2] = src.data[3 * indexs + 2] + 100;
    				
    			}
    		}
    	}
    

    3、遍历图像像素方法三:采用ptr指针方法
    说明:ptr指针尤其固定格式,就是先把图像看成(src.rows,1)的图像,ptr获取每个位置的地址,地址位置隐藏了列的数据,由于列表名就是列表的地址,所以ptr获取的地址就是此行中列这样一维数据的列表名称。这样通过下标就可以获取像素值

    for (int i = 0; i < src.rows; i++)
    	{
    		//获取第i行首地址,ptr与at结果差不多
    		uchar* src_rows_ptr = src.ptr<uchar>(i);
    		uchar* dst_rows_ptr = dst.ptr<uchar>(i);
    		for (int j = 0; j < src.cols; j++)
    		{
    			//每行指针的地址,又代表一行数组名称,因此下面就是遍历一行中的列数组数据
    
    			dst_rows_ptr[j] = src_rows_ptr[j] + 100;
    		}
    	}
    

    4、遍历彩色图像像素方法三:采用ptr指针方法
    说明:彩色图像的ptr就是在灰度的基础上,把(src.rows,1)处的地址看成是(src.cols,3)的二维数组,也是通过数组名(ptr获取的地址)来索引下标获取像素值。

    for (int i = 0; i < src.rows; i++)
    	{
    		//获取第i行首地址,首地址又是第一个数据,是三通道,所以是Vec3b
    		// 可以理解为三维数组,i个(j,3)维数组
    		Vec3b* src_rows_ptr = src.ptr<Vec3b>(i);
    		Vec3b* dst1_rows_ptr = dst1.ptr<Vec3b>(i);
    		for (int j = 0; j < src.cols; j++)
    		{
    			//每行指针的地址,又代表一行数组名称和第一个数据,因此下面就是遍历一行中的列数组数据
    			//可以理解,每行是一个二维数组(j,3)维度
    			dst1_rows_ptr[j][0]= src_rows_ptr[j][0]+100;
    			dst1_rows_ptr[j][1] = src_rows_ptr[j][1]+100;
    			dst1_rows_ptr[j][2] = src_rows_ptr[j][2]+100;
    		}
    	}
    

    5、针对at和ptr有很多人容易理解at,却理解不了ptr,下面讲一个用at生成ptr模式的解析例子
    说明:这是为了对比at和ptr而增加的,主要是获取at(i,0)位置处的地址,将其看成数值名称,通过下标索引像素值,和ptr原理一样,只是获取地址的方式不一样(数组名)

    5.1 遍历灰度图像像素方法五:采用at方法,使用ptr模式

    	for (int i = 0; i < src.rows; i++)
    	{
    		//将灰度图片看成(src.rows,1)维度的二维矩阵,获取(i,0)数据的地址
    		uchar* src_rows_ptr = &(src.at<uchar>(i, 0));
    	    uchar* dst_rows_ptr = &(dst.at<uchar>(i, 0));
    
    		for (int j = 0; j < src.cols; j++)
    		{
    			//将(i,0)数据的地址下的内容看成是一维数组,(i,0)数据的地址是一维数组的名字
    			dst_rows_ptr[j] = src_rows_ptr[j] + 100;
    		}
    	}
    

    5.2 遍历灰度图像像素方法六:采用at方法,使用ptr模式

    for (int i = 0; i < src.rows; i++)
    	{
    		//将彩色图片看成(src.rows,1)维度的二维矩阵,获取(i,0)数据的地址
    		Vec3b* src_rows_ptr = &(src.at<Vec3b>(i, 0));
    		Vec3b* dst1_rows_ptr = &(dst1.at<Vec3b>(i, 0));
    
    		for (int j = 0; j < src.cols; j++)
    		{
    			//将(i,0)数据的地址下的内容看成是二维数组,(i,0)数据的地址是二维数组的名字
    			dst1_rows_ptr[j][0] = src_rows_ptr[j](0) + 100;
    			dst1_rows_ptr[j][1] = src_rows_ptr[j](1) + 100;
    			dst1_rows_ptr[j][2] = src_rows_ptr[j](2) + 100;
    		}
    	}
    

    综上所述:使用ptr指针效率非常高,大家普遍使用的是at和ptr方法;使用的时候,一定要规范格式;
    其中:at<类型>(i,j)
    ptr<类型>(i)

    有不理解的,欢迎留言交流

    附上整个流程main.cpp
    使用方式:需要测试哪个方法,取消注释就行;

    #include<iostream>
    #include<opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
    	Mat src = imread("C:\\Users\\tudejiang\\Desktop\\1.jpg",1);
    	if (src.empty())
    	{
    		cout << "没有加载成功图片" << endl;
    		return -1;
    	}
    	imshow("src",src);
    	Mat dst = Mat(src.size(), CV_8UC1);
    	Mat dst1 = Mat(src.size(), CV_8UC3);
    
    	//遍历图像像素方法一:通过at<type>(i,j)坐标指针
    	/*for (int i = 0; i < src.rows; i++)
    	{
    		for (int j = 0; j < src.cols; j++)
    		{
    			if (src.channels() == 1)
    			{
    				dst.at<uchar>(i, j) = src.at<uchar>(i, j) + 100;
    			}
    			else if (src.channels() ==3)
    			{
    				dst1.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0] + 100;
    				dst1.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1] + 100;
    				dst1.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2] + 100;
    			}
    		}
    	}*/
    
    	//遍历图像像素方法二:data遍历索引法
    	//for (int i = 0; i < src.rows; i++)
    	//{
    	//	for (int j = 0; j < src.cols; j++)
    	//	{
    	//		if (src.channels() == 1)
    	//		{
    	//			//图像数组是逐行逐列顺序排列的,也就是第一行,全列,第二行全列的走
    	//			int indexs = i * src.cols + j;
    	//			dst.data[indexs] = src.data[indexs] + 100;
    	//		}
    	//		else if (src.channels() == 3)
    	//		{
    	//			int indexs = i * src.cols + j;
    	//			//在彩色图像中,每个indexs又是三个通过的数组
    	//			dst1.data[3 * indexs + 0] = src.data[3 * indexs + 0] + 100;
    	//			dst1.data[3 * indexs + 1] = src.data[3 * indexs + 1] + 100;
    	//			dst1.data[3 * indexs + 2] = src.data[3 * indexs + 2] + 100;
    	//			
    	//		}
    	//	}
    	//}
    	//遍历灰度图像像素方法三:采用ptr指针方法
    	//for (int i = 0; i < src.rows; i++)
    	//{
    	//	//获取第i行首地址,ptr与at结果差不多
    	//	uchar* src_rows_ptr = src.ptr<uchar>(i);
    	//	uchar* dst_rows_ptr = dst.ptr<uchar>(i);
    	//	for (int j = 0; j < src.cols; j++)
    	//	{
    	//		//每行指针的地址,又代表一行数组名称,因此下面就是遍历一行中的列数组数据
    
    	//		dst_rows_ptr[j] = src_rows_ptr[j] + 100;
    	//	}
    	//}
    	//遍历彩色图像像素方法四:采用ptr指针方法
    	//for (int i = 0; i < src.rows; i++)
    	//{
    	//	//获取第i行首地址,首地址又是第一个数据,是三通道,所以是Vec3b
    	//	// 可以理解为三维数组,i个(j,3)维数组
    	//	Vec3b* src_rows_ptr = src.ptr<Vec3b>(i);
    	//	Vec3b* dst1_rows_ptr = dst1.ptr<Vec3b>(i);
    	//	for (int j = 0; j < src.cols; j++)
    	//	{
    	//		//每行指针的地址,又代表一行数组名称和第一个数据,因此下面就是遍历一行中的列数组数据
    	//		//可以理解,每行是一个二维数组(j,3)维度
    	//		dst1_rows_ptr[j][0]= src_rows_ptr[j][0]+100;
    	//		dst1_rows_ptr[j][1] = src_rows_ptr[j][1]+100;
    	//		dst1_rows_ptr[j][2] = src_rows_ptr[j][2]+100;
    	//	}
    	//}
    	//遍历灰度图像像素方法五:采用at方法,使用ptr模式
    	//for (int i = 0; i < src.rows; i++)
    	//{
    	//	//将灰度图片看成(src.rows,1)维度的二维矩阵,获取(i,0)数据的地址
    	//	uchar* src_rows_ptr = &(src.at<uchar>(i, 0));
    	//	uchar* dst_rows_ptr = &(dst.at<uchar>(i, 0));
    
    	//	for (int j = 0; j < src.cols; j++)
    	//	{
    	//		//将(i,0)数据的地址下的内容看成是一维数组,(i,0)数据的地址是一维数组的名字
    	//		dst_rows_ptr[j] = src_rows_ptr[j] + 100;
    	//	}
    	//}
    	//imshow("dst1", dst);
    	//遍历灰度图像像素方法六:采用at方法,使用ptr模式
    	for (int i = 0; i < src.rows; i++)
    	{
    		//将彩色图片看成(src.rows,1)维度的二维矩阵,获取(i,0)数据的地址
    		Vec3b* src_rows_ptr = &(src.at<Vec3b>(i, 0));
    		Vec3b* dst1_rows_ptr = &(dst1.at<Vec3b>(i, 0));
    
    		for (int j = 0; j < src.cols; j++)
    		{
    			//将(i,0)数据的地址下的内容看成是二维数组,(i,0)数据的地址是二维数组的名字
    			dst1_rows_ptr[j][0] = src_rows_ptr[j](0) + 100;
    			dst1_rows_ptr[j][1] = src_rows_ptr[j](1) + 100;
    			dst1_rows_ptr[j][2] = src_rows_ptr[j](2) + 100;
    		}
    	}
    	imshow("dst1", dst1);
    	waitKey(0);
    	return 0;
    }
    
    

     

    展开全文
  • 图的存储方法采用邻接表存储。 一.树与图的深度优先遍历,树的DFS序,深度与重心、 树与图的深度优先遍历 树可以看作时边数N-1的无向图,图就是图,这样可以达到树与图遍历的代码统一。 void DFS(int x) { //O(n+m) ...

    图的存储方法采用邻接表存储。

    一.树与图的深度优先遍历,树的DFS序,深度与重心、

    树与图的深度优先遍历

    树可以看作时边数N-1的无向图,图就是图,这样可以达到树与图遍历的代码统一。
    void DFS(int x) {   //O(n+m) 
    	vis[x] = 1;
    	for(int i = head[x]; i;i = Next[i]) {
    		int v = var[i];
    		if(vis) continue;
    		DFS(v);
     	}
    } 
    
    

    每个点只走一次,每条边只走一次,如果时无向图则正反各访问一次。以此代码为框架可以统计很多树和图的基本信息。

    树的DFS序
    一般来讲,我们在对树进行深度优先遍历时,对于每个节点,在刚进入递归的时候以及回溯之前各记录一次该点的编号,这样最后生成的长度为2N的序列就时树的DFS序

    //树的dfs序列 
    void dfs(int u) { //把树看做n-1的无向图  O(n+m) 
    	vis[u] = 1; //记录遍历过的节点 
    	dfn[++cnt] = u; //时间戳 
    	for(int i = head[u]; i; i = Next[i]) {
    		int v = var[i];
    		if(vis[v]) continue;
    		dfs(v); 
    	}
    	dfn[++cnt] = u;
    }
    //dfn存储的就是 树的dfs序,一般来说,我们在对树进行深度优先遍历的时候,
    //对于每一个节点进入的时候记录一个序号,在回溯之前记录一个序号,得到的序列就是dfs序 
    

    通过求树的DFS序我可以把子树的统计转化为序列上的区间统计问题。

    树的深度
    根节点深度为0,子节点深度 = 父节点 + 1。由此可以见在树上对于边(x,y),d[x] = d[y] + 1。我们在深度优先遍历的时候结合自顶向下的递推就可以很好的统计出树上各各节点的深度信息。

    
    ```cpp
    //树的深度 根深度为0 
    int d[maxn];
    void getDeeps(int x) { // //O(n+m) 
    	vis[x] = 1;
    	for(int i = head[x]; i; i = Next[i]) {
    		int v = var[i];
    		if(vis[v]) continue;
    		d[v] = d[x] + 1; //从根往下递推 计算深度 
    		getDeeps(v); 
    	}
    } 
    

    当然也可以使用广搜,层序遍历来求解。

    void bfs() {//O(n+m) 
    	queue<int> q;
    	memset(vis,0,sizeof(vis));
    	d[1] = 1; q.push(1);
    	while(q.size()) {
    		int x = q.front();
    		q.pop();
    		for(int i = head[x]; i;i = Next[i]) {
    			int y = var[i];
    			if(d[y]) continue;
    			d[y] = d[x] + 1;
    			q.push(y);	
    		}
    	}
    }
    

    树的重心
    深度信息我们是在树上自顶向下统计,对于每个节点的子树有多少节点这个问题我们就要自底向上的统计。
    树重心的定义:对于一个节点x,如果我们把它从树中删除,那么原树可能会分成若干不相邻的部分,其中每一部分都是一个子树,设max_part(x)表示删除x后生成的子树中最大的一颗的大小,时max_part等于最小值的点p就是树的重心。

    //树的重心 
    /*
    	定义:对于一个节点x,去除它后产生的子树的大小的最大值记作max_part(x),
    	使max_part函数达到最小值的节点p就是树的重心 
    */ 
    int size[maxn];
    int ans = 0x7f7f7f7f;
    int P;
    void getCenterOfGravity(int x) {O(n+m) 
    	vis[x] = 1;
    	size[x] = 1;
    	int max_part = 0;
    	for(int i = head[x]; i; i = Next[i]) {
    		int v = var[i];
    		if(vis[v]) continue;
    		getCenterOfGravity(v);
    		size[x] += size[v];
    		max_part = max(max_part,size[v]); //获得最大的子树 
    	}
    	
    	max_part = max(max_part,n-size[x]); //去除自身节点与子树后剩下的部分
    	if(max_part < ans) {
    		ans = max_part; //ans记录max_part的最小值 
    		P = x; //P记录重心 
    	} 
    	
    } 
    

    2.树与图的广度优先遍历,拓扑排序,图联通块的划分

    连通块的划分
    上面的深度优先遍历代码,从x开始遍历就能访问从x灯达到的所有点与边。因此采用多次深度优先遍历可以划分出一张无向图中的各个连通块,同理对森林中使用次方法可以划分出每一个树。

    //图连通块的划分
    int block = 0; //第几块 
    int number[maxn]; //编号  
    void DFS(int x) { //遍历连通块  //O(n+m) 
    	number[x] = block; //属于那个连通块 
    	for(int i = head[x]; i;i = Next[i]) {
    		int v = var[i];
    		if(number[x]) continue;
    		DFS(v);
     	}
    }
    
    void main() {
    	for(int i = 1; i <= n; i ++) {
    		if(number[i]) continue;
    			block++;
    			dfs(i);
    	}
    	return 0;
    }
    
    

    树的深度优先遍历
    利用队列先进先出的特点来进行层序遍历,也能很好的统计深度信息。

    void bfs() {//O(n+m) 
    	queue<int> q;
    	memset(vis,0,sizeof(vis));
    	d[1] = 1; q.push(1);
    	while(q.size()) {
    		int x = q.front();
    		q.pop();
    		for(int i = head[x]; i;i = Next[i]) {
    			int y = var[i];
    			if(d[y]) continue;
    			d[y] = d[x] + 1;
    			q.push(y);	
    		}
    	}
    }
    

    利用bfs还可以求树的层序遍历,树的层数,树每层的节点数,树的宽度,等信息。

    拓扑排序
    给定一张有向无环图,若一个由图中点构成的序列A满足:对于图中的每一条边(x,y),x在A中都出现在y之前,那么A就是这个有向无环图的拓扑序,求解这个拓扑序的过程就为拓扑排序。
    求解拓扑排序的思路:
    拓扑排序的思路非常简单,我们只需要不断选择图中入度为0的节点x,然后把x连向的点入度减一,在结合广搜的框架可以高效的求解它。
    1.建立空拓扑序A
    2.初始化队列,把所有入度为0的点加入队列
    3.取出队首节点x,把x加入序列A的末尾
    4.对于x出发的每一条(x,y),deg[y]–,若deg[y] 等于 0 则加入队列
    5.重复3~4直到队列为空,此时A为所求*

    vector<int> topOrder; //步骤1
    int deg[maxn];//存放点的入度
    void TopSort() {
    	queue<int> q; //
    	for(int i = 1; i <= n ;i ++) {
    		if(!deg[i]) q.push(i); //步骤2
    	}
    	while(q.size()) {
    		int x = q.front(); q.pop(); 
    		topOrder.push_back(x); //记录拓扑序 //步骤3
    		for(int i = head[x]; i ;i = Next[i]) {  //步骤4
    			int y = var[i];--deg[y];
    			if(deg[y] == 0) q.push(y);
    		}
    	}
    }
    

    拓扑排序时可以判断有向图是否存在环,我们可以在任意有向图执行完毕上述步骤之后,检查拓扑序长度是否小于图中节点数目,如果小于则有环。

    展开全文
  • /*有向图的DFS基本实现方法,-1表示不能走*/ package app; import java.util.Scanner; // import java.util.Queue; class Tu2{ public static int maxn = 100; static boolean []vis = new boolean[maxn]; ...
    
    /*有向图的DFS基本实现方法,-1表示不能走*/
    
    package app;
    
    import java.util.Scanner;
    // import java.util.Queue;
    class Tu2{
        public static int maxn = 100;
        static boolean []vis = new boolean[maxn];
        static int[][] G = new int[maxn][maxn];  //存邻接矩阵
        static int n;                            //有几个点
        static char[] vhave = new char[maxn];    //存点
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            
            n = input.nextInt();
            for(int i=0;i<n;i++){                //初始化标记矩阵
                vis[i] = false;
            }
            for(int i=0;i<n;i++){                //输入邻接矩阵
                for(int j=0;j<n;j++){
                    G[i][j] = input.nextInt();
                }
            }
            System.out.println();
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    System.out.print(G[i][j]+" ");
                    if(j == n-1){
                        System.out.println();
                    }
                }
            }
            for(int i=0;i<n;i++){                //输入点的符号
                vhave[i] = input.next().charAt(0);
            }
            input.close();
            DFSTrave();
        }
        public static void DFS(int u, int depth){
            vis[u] = true;                              //将u设置为已访问
            System.out.print(vhave[u]+" ");             //输出u对应的点的标号
            for(int v=0;v<n;v++){                       //从u访问可以访问的所有点
                if(vis[v] == false  &&  G[u][v] != -1 ){  //如果这个点没有被访问过且这个点是能到达的,那么入栈
                    DFS(v, depth+1);
                }
            }
        }
        public static void DFSTrave(){                //遍历图,从第一个点开始进入DFS
            for(int u=0;u<n;u++){ 
                if(vis[u] == false){                  //如果没有被访问过,那么入栈
                    DFS(u, 1);
                }
            }
        }
    }
    
    展开全文
  • 图的形式如下所示: 分别使用 BFS DFS 来对图进行遍历;并利用BFS 来求 无权重图的无向图 的最短路径 1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 graph ={ 4 'A':['B','C'], 5 'B':['A','C','...
  • OpenCV遍历图像

    2020-10-11 20:48:31
    在图形处理中,遍历每个像素点是最基本的功能,是做算法基础,这篇文章来总结一下OpenCV遍历图像几种方法
  • 图像的点或矩阵中的元素,是我们进行运算时的基本元素,所以遍历图像的操作是经常要用到的,本文的代码用四种方式实现图像的遍历。 我们通过元素遍历实现对图像降色彩处理,因为256*256*256种颜色实在太多了,在...
  • 图的遍历

    2018-11-06 13:37:39
    图的遍历图的操作算法中最基本也是最重要的方法,与树的遍历相似,这里也分为深度优先遍历和宽度优先遍历,通过深度优先遍历得到的顶点序列称为该图的深度优先序列(Depth-First Search,DFS序列),通过宽度优先...
  • 3.掌握图的深度优先搜索和广度优先搜索遍历方法及其计算机的实现。 4.理解最小生成树的有关算法 二、实验内容 1.用邻接表作为图的存储结构建立一个图,并对此图分别进行深度优先搜索和广度优先搜索遍历...
  • 5.3.1图的遍历

    2016-09-13 18:27:03
    图的遍历是指从图中的某一顶点出发,按照某种搜索方法沿着图中的边对图中的所有顶点访问一次且仅访问一次。注意到树是一种特殊的图,所以树的遍历实际上也可以看作是一种特殊图的遍历图的遍历图的一种最基本的...
  • 本文实例讲述了JavaScript实现二叉树定义、遍历及查找的方法。分享给大家供大家参考,具体如下: 二叉树(binary tree) 在写这篇文章之前说一下数据结构和算法这个系列,这个系列包含了很多东西,比如啥子排序,...
  • 深度优先遍历基本思想:图的深度优先搜素(Depth FirstSearch):DFS 深度优先遍历,从初始访问结点出发,初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点。 然后再以这个被访问的...
  • 原贴查看:https://blog.csdn.net/qq_34528297/article/details/73008288原先的知识没好好学,导致现在很多都忘了,或者说以前就没弄懂过。...其中G表示一个图,V是图的顶点的集合,E是图的边的集合。有跟多条边...
  • OpenCV中图像像素是以矩阵形式...下面介绍两种图像遍历方法方法一:指针遍历图像(最高效) #include "pch.h" #include <core.hpp> #include <highgui.hpp> #include <imgproc.hpp> ...
  • 实验目的 (1)掌握图的基本存储方法——邻接表和邻接矩阵。 (2)熟练掌握图的两种遍历方法
  • 在大多数图像处理中,为了计算,往往需要遍历图像所有像素,高效地遍历方法是非常重要 第一种:指针法 例子:减少图像中颜色数目 如将256x256x256颜色数目减到32x32x32 原始图像中每个颜色都替换为它...
  • 图的创建与遍历

    2013-01-08 00:51:13
    1. 掌握图的基本存储方法; 2. 熟练掌握图的两种搜索路径的遍历方法 深度优先遍历,广度优先遍历
  • 图的遍历主要有两种算法: 广度优先搜索(Breadth-First-Search)和深度优先搜索(Depth-First-Search)。 那么就先来说一下深度优先搜索吧。 深度优先搜索算法所遵循的搜索策略是尽可能“深”地搜索一个图。它...
  • 遍历图片上所有像素

    千次阅读 2013-09-08 21:14:22
    今天我主要是学着对图像中像素进行操作,如果像素值超过133,则将其设置成255。 这里碰到了几个问题: 1、 当图片为3通道时,怎么办 ...首先,用最基本的方法来看看: 结果如所示:      原 
  • 这里针对图的基本定义形式和两种常见的遍历方法(深度优先和广度优先)进行讨论。   图的结构  从直观的角度来看,我们常见的图一般是这样的: 或者如下图这样:  这两种图我们分别称其为无向图和有向图...
  • 对于二叉树的基本知识其中包括二叉树的遍历,以前有时候笔试题可能有这种题目,虽然比较简单,但是对于初学者可能往往记不太住; 二叉树的遍历方式简单来说有3种方式,前,中,后序遍历,一般采用递归算法,有的...
  • 二叉树初级应用及遍历 hello大家好,我们今天要介绍就是,Java中二叉树初级应用 ----遍历。 话不多说先放一张来了解一下什么是二叉树 这是我自己画一张简单二叉树图像,说到二叉树,首先我们要了解什么...
  • 有向图基本遍历算法

    千次阅读 2016-03-04 16:22:27
    1 图的表示 2. 有向图的遍历算法:深度优先 3. 有向图的遍历算法:广度优先 4 代码反思 5. 下载 ...1. 图的表示 ...1.1 图的定义 ...图G定义为V和E的集合G={V, E...1.2 图的表示方法 上面给出的数学上图的定义,那么在计

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,242
精华内容 496
关键字:

遍历图的基本方法