任务描述
本关任务:请你实现 Graph.cpp 里的int Graph_WidthFirst(Graph*g, int start, Edge* tree)
函数。 注意遵守约定:编号小的优先入队列。
相关知识
图 2 给出了对图 1 的无向图的存储结构图:每个顶点的名称由一个字符串描述,所有字符串的起始地址组织为一个数组,数组的起始地址为vetex
;顶点的相邻关系保存在相邻矩阵中,其起始地址为adj
,adj[i*n+j]
的值为 1 表示i
号顶点到j
号顶点有边,为 0 表示无边,其中n
是顶点个数,i
和j
是顶点在顶点表中的编号。 将n,vetex,adj
组织成结构:
struct Graph {
int n;//顶点数
char** vetex;
int* adj;
};
给定指向该结构的指针g
,就可以对图进行操作。
宽度优先遍历算法(伪代码):
WidthFirst(Graph, start)
//输入Graph是图,start是开始顶点的编号
//输出:tree_edge[i]=<from,to>是遍历树的一条边
//tree_edge[1..n-1]为遍历树的n-1条边
//tree_edge[0].to … tree_edge[n-1].to是遍历序列
QueueIn(<-1,start>)
k=0;
while(QueueNotEmpty) {
<a,b>=QueueOut;
if (unvisited(b)) {
visit(b); // visit b, and set a flag for b.
tree_edge[k++]=<a,b>; // add <a,b> to the tree
for each <b,c> in the Edge Set {
if (unvisited(c)) QueueIn(<b,c>); //约定:编号小的先入队列
}
}
}
对图1运行该算法的结果: 生成树的边是:<-1,A> <A,B> <A,C> <A,F> <B,D> <F,E>
; 宽度优先遍历的顶点访问次序是:A B C F D E。
编程要求
请你实现Graph.cpp
里的int Graph_WidthFirst(Graph*g, int start, Edge* tree)
函数。 注意遵守约定:编号小的优先入队列。
输入格式: 输入n
,顶点数; 输入n
个字符串,即n
个顶点的名称,其编号按输入次序是,0,...,n-1
; 输入若干数字对(a b)或<a b>
,(a b)
表示无向边,<a b>
表示有向边; 输入字符x
,表示边输入结束; 输入一个数start
,表示开始顶点的编号。
输出格式: 输出生成树的边序列,边的第start
个顶点构成的序列应是顶点访问序列。
以下是平台对 step1/Main.cpp 的测试样例: 样例输入
6 A B C D E F ( 0 1 ) ( 0 2 ) ( 0 5 ) ( 1 3 ) ( 1 5 ) ( 2 3 ) ( 4 5 ) x 0
样例输出
tree edges: <-1,A> <A,B> <A,C> <A,F> <B,D> <F,E> visit sequence: A B C F D E
实现代码
/*************************************************************
date: April 2017
copyright: Zhu En
DO NOT distribute this code without my permission.
**************************************************************/
// 顺序表操作实现文件
//
#include <stdio.h>
#include <stdlib.h>
#include "Seqlist.h"
SeqList* SL_Create(int maxlen)
// 创建一个顺序表。
// 与SqLst_Free()配对。
{
SeqList* slist=(SeqList*)malloc(sizeof(SeqList));
slist->data = (T*)malloc(sizeof(T)*maxlen);
slist->max=maxlen;
slist->len=0;
return slist;
}
void SL_Free(SeqList* slist)
// 释放/删除 顺序表。
// 与SqLst_Create()配对。
{
free(slist->data);
free(slist);
}
void SL_MakeEmpty(SeqList* slist)
// 置为空表。
{
slist->len=0;
}
int SL_Length(SeqList* slist)
// 获取长度。
{
return slist->len;
}
bool SL_IsEmpty(SeqList* slist)
// 判断顺序表是否空。
{
return 0==slist->len;
}
bool SL_IsFull(SeqList* slist)
// 判断顺序表是否满。
{
return slist->len==slist->max;
}
T SL_GetAt(SeqList* slist, int i)
// 获取顺序表slist的第i号结点数据。
// 返回第i号结点的值。
{
if(i<0||i>=slist->len) {
printf("SL_GetAt(): location error when reading elements of the slist!\n");
SL_Free(slist);
exit(0);
}
else
return slist->data[i];
}
void SL_SetAt(SeqList* slist, int i, T x)
// 设置第i号结点的值(对第i号结点的数据进行写)。
{
if(i<0||i>=slist->len) {
printf("SL_SetAt(): location error when setting elements of the slist!\n");
SL_Free(slist);
exit(0);
}
else
slist->data[i]=x;
}
bool SL_InsAt(SeqList* slist, int i, T x)
// 在顺序表的位置i插入结点x, 插入d[i]之前。
// i 的有效范围[0,plist->len]。
{
// 请在下面的Begin-End之间补充代码,插入结点。
/********** Begin *********/
for (int j = slist->len+1; j>=i; j--) slist->data[j] = slist->data[j-1];
slist->data[i] = x;
++slist->len;
/********** End **********/
}
T SL_DelAt(SeqList* slist, int i)
// 删除顺序表plist的第i号结点。
// i的有效范围应在[0,plist->len)内,否则会产生异常或错误。
// 返回被删除的数据元素的值。
{
// 在下面的Begin-End之间补充代码,删除第i号结点。
/********** Begin *********/
for (int j = i; j < slist->len; j++)
slist->data[j] = slist->data[j + 1];
--slist->len;
/********** End **********/
}
int SL_FindValue(SeqList* slist, T x)
// 在顺序表表中查找第一个值为x的结点,返回结点的编号。
// 返回值大于等于0时表示找到值为x的结点的编号,-1表示没有找到。
{
int i=0;
while(i<slist->len && slist->data[i]!=x) i++;
if (i<slist->len) return i;
else return -1;
}
int SL_DelValue(SeqList* slist, T x)
// 删除第一个值为x的结点。
// 存在值为x的结点则返回结点编号, 未找到返回-1。
{
// 在下面的Begin-End之间补充代码,删除第一个值为 x 的结点。
/********** Begin *********/
int i=0;
while (i < slist->len && slist->data[i] != x) i++;
if (i == slist->len)
return -1;
else
{
for (int j = i; j < slist->len; j++)
slist->data[j] = slist->data[j + 1];
--slist->len;
return i;
}
/********** End **********/
}
void SL_Print(SeqList* slist)
// 打印整个顺序表。
{
if (slist->len==0) {
printf("The slist is empty.\n");
return;
}
//printf("The slist contains: ");
for (int i=0; i<slist->len; i++) {
printf("%d ", slist->data[i]);
}
printf("\n");
}
欢迎大家留言讨论