图的遍历与最小生成树问题

图的遍历

分为深度优先级遍历与广度优先级遍历。
深度优先级遍历DepthFirstSearch,类似于一条路走到尽,如果成功则结束,如果失败则一个个回溯会上一个顶点判断下一条未走过的路径,在进行遍历,直到成功为止,最坏打算为全部结点都遍历一遍。
实现原理:利用栈模型,将已走过的结点都入栈,如果判断无路可走且未达到终点则弹栈出上一个结点判断是否有下一条路走,直到终点或者栈为空才遍历完毕。

广度优先级遍历,类似于层次遍历,各个方向都轮流走一步,直到最低层。
实现原理:利用队列模型,将已走过的结点都入队,即一层走完后回到当前层的第一个结点判断是否有路可走进入下一层,直到终点或队列为空才遍历完毕。
特点:可以找到最短路径

深度优先级遍历代码:

void DFS_Graph(p_adjMatlist list)
{
	int i=0,j=0;
	bool visited[list->vex_num];
	p_Stack S = NULL;
	//初始化数组
	for( i=0; i<list->vex_num; i++ )
	{
		visited[i] = false;
	}
	//初始化栈空间
	Stack_Create(&S);
	//深度优先级遍历
	printf("深度优先级遍历结果:");
	i = 0;
	printf("%c", list->vex_buf[i]);
	visited[i] = true;
	Stack_Push(S, i);
	while( !Stack_Empty(S) )
	{
		for(j=0; j<list->vex_num; j++){
			if(i==j)
				continue;
			if( list->adjmat[i][j] != 0 && !visited[j])
			{
				printf("%c", list->vex_buf[j]);
				visited[j] = true;
				Stack_Push(S, i);
				i = j;
				break;
			}
		}
		if( j == list->vex_num )
			Stack_pop(S, &i);
	}
	printf("\n");
}

广度优先级遍历代码:

void BFS_Graph(p_adjMatlist list)
{
	int i=0,j=0;
	bool visited[list->vex_num];
	p_seqqueue Q;
	//初始化数组
	for( i=0; i<list->vex_num; i++ )
	{
		visited[i] = false;
	}
	//初始化队列
	seqqueue_init(&Q);
	printf("广度优先遍历结果:");
	for( i=0; i<list->vex_num; i++ )
	{
		if( !visited[i] ){
			printf("%c", list->vex_buf[i]);
			visited[i] = true;
			seqqueue_insert(Q, i);
		}
		while( !seqqueue_empty(Q) )
		{
			seqqueue_out(Q, &i);
			for( j=0; j<list->vex_num; j++ )
			{
				//忽略对角线
				if( i==j )
					continue;
				//有连接
				if( list->adjmat[i][j] != 0 && !visited[j] )
				{
					printf("%c", list->vex_buf[j]);
					visited[j] = true;
					seqqueue_insert(Q, j);
				}
			}
		}
	}
	printf("\n");
}

生成最小树

普里姆算法prim:以当前顶点为作为标准,遍历下一个带权值最小的顶点,从而获得最小生成树。遍历时需记录已走过的结点和每个顶点权值之和。适用于稠密图,顶点少边多
克鲁斯卡尔kruskal:以当前边作为标准,遍历下一条带权值最小的边,适用于稀疏图,顶点多变少。

你可能感兴趣的:(数据结构,图的遍历与最小生成树)