头歌数据结构-实现图的广度优先遍历

第1关:实现图的宽度优先遍历

本关任务:请你实现 graph.cpp 里的int Graph_WidthFirst(Graph*g, int start, Edge* tree)函数。 注意遵守约定:编号小的优先入队列。

相关知识

头歌数据结构-实现图的广度优先遍历_第1张图片

头歌数据结构-实现图的广度优先遍历_第2张图片

图 2 给出了对图 1 的无向图的存储结构图:每个顶点的名称由一个字符串描述,所有字符串的起始地址组织为一个数组,数组的起始地址为vetex;顶点的相邻关系保存在相邻矩阵中,其起始地址为adjadj[i*n+j]的值为 1 表示i号顶点到j号顶点有边,为 0 表示无边,其中n是顶点个数,ij是顶点在顶点表中的编号。

//Graph
///
#include 
#include 
#include 
#include "Graph.h"
/

Graph* Graph_Create(int n)
{
	Graph* g=(Graph*)malloc(sizeof(Graph));
	g->n=n;
	g->vetex=(char**)malloc(sizeof(char*)*n);
	int i;
	for (i=0; ivetex[i] = NULL;
	g->adj=(int*)malloc(sizeof(int)*n*n);
	int j;
	for(i=0; iadj[i*n+j]=0;
		}
	}
	return g;
}

void Graph_Free(Graph* g)
{
	free(g->adj);
	int i;
	for (i=0; in; i++) free(g->vetex[i]);
	free(g->vetex);
	free(g);
}

int Graph_WidthFirst(Graph*g, int start, Edge* tree)
//从start号顶点出发宽度优先遍历,(编号从0开始)
//返回访问到的顶点数,
//tree[]输出遍历树
//返回的tree[0]是(-1, start), 
//真正的遍历树保存在tree[1..return-1], return是返回值
//顶点的访问次序依次为tree[0].to, tree[1].to,  ..., tree[return-1].to
//输入时,tree[]的长度至少为顶点数
//返回值是从start出发访问到的顶点数
{
	const int MAX=1000;
	Edge queue[MAX];
	int head=0, tail=0;
#define In__(a,b)  {queue[tail].from=a; queue[tail].to=b; tail=(tail+1)%MAX;}/
#define Out__(a,b)  {a=queue[head].from; b=queue[head].to; head=(head+1)%MAX;}//
#define QueueNotEmpty (head!=tail?1:0)///
#define HasEdge(i,j)  (g->adj[(i)*g->n+(j)]==1)

	char* visited=(char*)malloc(sizeof(char)*g->n);
	memset(visited, 0, sizeof(char)*g->n);

	int parent=-1;  
	int curr=start;
	In__(parent, curr); 
	int k=0; //已经访问的结点数
	/*请在BEGIN和END之间实现你的代码*/
    /*****BEGIN*****/
    while(QueueNotEmpty)
	{
		Out__(parent,curr);//out是输出值,不需要预先给他值,当函数执行完毕后可以从这个变量获取输出的数据
		if(visited[curr])
		continue;
		visited[curr]=1;
		tree[k].from=parent;
		tree[k].to=curr;
		k++;
		int j;
		for(j=0;jn;j++)
		{
			if(HasEdge(curr,j)&&!visited[j])
			In__(curr,j);
		}
	}
    /*****END*******/
	return k;
#undef In__//
#undef Out__///
#undef QueueNotEmpty
#undef HasEdge
}

你可能感兴趣的:(数据结构,数据结构,宽度优先,算法)