第四周作业--1图的表示,2无向图的DFS算法,3有向图找环;

#include <iostream>
#include <fstream>
using namespace std;

#define MAX_EDGE 100
#define SAFE_DEL(p) { if (p!=NULL) { delete [] p;}}


bool *visited;
int *pre;
int *post;
int *ccnum;
int *Descpost;

int ImportToArray(const char *filename,int *array)	//将filename内的纯数字文本导入数组array;
{
	int count=0;
	ifstream fin;
	fin.open(filename);
	if( fin.fail() )
	{
		cout<<"file read fail!"<<endl;
		return -1;
	}
	while( fin.eof() ==false )
		fin>>array[count++];
	fin.close();
	return count;
}

int ExportWithGraphArray(const char *filename,bool **GraphArray,int vertexNum)
{
	ofstream fout;
	fout.open(filename);
	if(fout.fail())
	{
		cout<<"file wirte fail"<<endl;
		return -1;
	}


	for(int i=0;i<vertexNum;i++)
		fout<<"\t"<<i;
	fout<<endl;
	for(int i=0;i<vertexNum;i++)
	{
		fout<<i;
		for(int j=0;j<vertexNum;j++)
			fout<<"\t"<<GraphArray[i][j];
		fout<<endl;
	}
	fout.close();
}


void GraphRepresentation(int *array,int count,bool **GraphArray,int vertexNum)	//从文本中获得
{
	//从数组中获得矩阵信息
	int row,col;
	for(int i=2;i<count;)
	{
		row=array[i++];
		col=array[i++];
		GraphArray[row][col]=true;		//有向图
		//GraphArray[col][row]=true;		//无向图加上此行
	}

	//将邻接矩阵写入文件
	ExportWithGraphArray("tinyDG_matrix.txt",GraphArray,vertexNum);

	//显示邻接矩阵
	for(int i=0;i<vertexNum;i++)
	{
		for(int j=0;j<vertexNum;j++)
		{
			cout<<GraphArray[i][j]<<" ";
		}
		cout<<endl;
	}
}

void explore(bool **GraphArray,int cc,int v,int vertexNum)
{
	static int Clock=0;
	visited[v]=true;
	cout<<v<<" ";
	{
		pre[v]=++Clock;
		ccnum[v]=cc;
	}
	for(int i=0;i<vertexNum;i++)
	{
		if (true==GraphArray[v][i] && false==visited[i]) explore(GraphArray,cc,i,vertexNum);
	}
	{
		post[v]=++Clock;
	}
}

void GraphDFS(bool **GraphArray,int vertexNum)
{	
	int cc=1;
	//初始需要的数组
	memset(visited,0,vertexNum*sizeof(bool));
	
	//遍历结点
	for(int i=0;i<vertexNum;i++)
		if (false==visited[i]) 
		{
				explore(GraphArray,cc,i,vertexNum);
				cc++;
		}
	
	//显示各顶点遍历结果
	cout<<endl;
	cout<<"\tccnum\t"<<"pre\t"<<"post"<<endl;
	for(int i=0;i<vertexNum;i++)
	{
		cout<<i<<"\t"<<ccnum[i]<<"\t"<<pre[i]<<"\t"<<post[i]<<endl;
	}
}
int *hoopstack;

bool isInStack(int *stack,int n,int find)
{
	for(int i=0;i<n;i++)
		if(find==stack[i]) return true;
	return false;
}

void exploreHoop(bool **GraphArray,int vertexNum,int u,int v) //回边为u->v
{
	static int k=0;
	hoopstack[k++]=v;	//stack push
	if(v!=u)
	{
		for(int i=0;i<vertexNum;i++)
		{
			if( true==GraphArray[v][i] && (false == isInStack(hoopstack,k-1,i)) ) //有v->i并且i不在stack里
				exploreHoop(GraphArray,vertexNum,u,i); //此处u,i不再做回边
		}
		k--;	//stack pop
	}
	else
	{
		for(int i=0;i<k;i++)
			cout<<hoopstack[i]<<" ";
		cout<<endl;
		k--;	//stack pop
	}
}

bool GraphDAG(bool **GraphArray,int vertexNum) //判断图中是否有环,有则输出环
{
	bool flag=false;
	hoopstack=new int[vertexNum];
	for(int i=0;i<vertexNum;i++)
		for(int j=0;j<vertexNum;j++)
			if( true==GraphArray[i][j] && post[i]<post[j]) //若i->j,且post[i]<post[j],则为回边
			{
				flag=true;
				//memset(visited,0,vertexNum*sizeof(bool));
				exploreHoop(GraphArray,vertexNum,i,j);
			}
	SAFE_DEL(hoopstack);
	return flag;
}


void main()
{
	int *array=new int[MAX_EDGE*2];
	int count=ImportToArray("tinyDG.txt",array);//注意文本最后有无空行



	int vertexNum=array[0],edgeNum=array[1];
	//动态创建各数组
	bool* *GraphArryR=new bool*[vertexNum];
	for(int i=0;i<vertexNum;i++)
	{
		GraphArryR[i]=new bool[vertexNum];
		for(int j=0;j<vertexNum;j++)
			GraphArryR[i][j]=false;
	}

	visited=new bool[vertexNum];
	pre=new int[vertexNum];
	post=new int[vertexNum];
	ccnum=new int[vertexNum];
//	Descpost=new int[vertexNum];
	
	GraphRepresentation(array,count-1,GraphArryR,vertexNum);

	cout<<"遍历结果:"<<endl;
	GraphDFS(GraphArryR,vertexNum);
	cout<<"图中环有:"<<endl;
	GraphDAG(GraphArryR,vertexNum);


	///
	//销毁动态数组

	SAFE_DEL(ccnum);
	SAFE_DEL(post);
	SAFE_DEL(pre);
	SAFE_DEL(visited);
//	SAFE_DEL(Descpost);
	for(int i=0;i<vertexNum;i++)
		SAFE_DEL(GraphArryR[i]);
	SAFE_DEL(GraphArryR);
	SAFE_DEL(array);
}


 

一,二题结果图,右边为题图

第三题结果图:


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值