六度空间

  • 题目来源;

浙江大学在慕课网上开设的《数据结构》课,陈越老师、何钦铭老师主讲,课后作业的一道题。

  • 题目描述:
    1327401-20190820110046172-744084355.png

1327401-20190820110053350-1467647984.png

  • 题目思路:

使用BFS即可。

  • C语言实现
#define _CRT_SECURE_NO_WARNINGS
//使用邻接表来存储图
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// #include "queue.h"

/************************/
// #include "queue.h"
struct QNode
{
    int* Data;  //存储元素的数组
    int Front;  //队列的头指针
    int Rear;  //队列的尾指针
    int MaxSize;  //队列的最大容量
};
//创建一个队列
struct QNode* CreateQueue(int MaxSize)
{
    struct QNode* Q = (struct QNode*)malloc(sizeof(struct QNode));
    Q->Data = (int *)malloc(MaxSize * sizeof(int));
    Q->Front = Q->Rear = 0;
    Q->MaxSize = MaxSize;
    return Q;
}

bool IsFull(struct QNode* Q)
{
    return ((Q->Rear + 1) % Q->MaxSize) == Q->Front;
}

//在队列尾插入一个元素
//参数 struct QNode* Q 要操作的队列
//     int x  待插入的元素
bool AddQ(struct QNode* Q, int x)
{
    if (IsFull(Q))  //判断队列是否为空
    {
        printf("队列满,不能再插入元素\n");
        return false;
    }
    else
    {
        Q->Rear = (Q->Rear + 1) % Q->MaxSize;
        Q->Data[Q->Rear] = x;
        return true;
    }
}

//判断队列是否为空
bool IsEmpty(struct QNode* Q)
{
    return (Q->Front == Q->Rear);
}
//在队列头部删除一个元素
int DeleteQ(struct QNode* Q)
{
    if (IsEmpty(Q))
    {
        printf("队列为空\n");
        return false;
    }
    else
    {
        Q->Front = (Q->Front + 1) % Q->MaxSize;
        return Q->Data[Q->Front];
    }

}
/****************************/
#define MaxVerterNum 1000

bool Visited[MaxVerterNum];
//边的定义
struct ENode
{
    int V1;
    int V2;  //有向边<V1,V2>
    int Weight;  //权重
};

//邻接点的定义
struct AdjNode
{
    int AdjV;  //邻接点的下标
    int Weight;  //边的权值
    struct AdjNode* Next;  //指向下一个邻接点的指针
};

//顶点表头结点的定义
typedef struct Vnode
{
    struct AdjNode* FirstEdge;  //边表头指针
    char Data;  //存储顶点的数据  //这里设为字符型
}AdjList[MaxVerterNum];

//图节点的定义
struct GNode
{
    int Nv;  //顶点数
    int Ne;  //边数
    AdjList G;  //邻接表
};

struct GNode* CreateGraph(int VertexNum)
{
    //初始化一个有VertexNum个顶点但没有边的图
    int V;
    struct GNode* Graph;
    
    //建立图
    Graph = (struct GNode*)malloc(sizeof(struct GNode));
    Graph->Ne = 0;
    Graph->Nv = VertexNum;

    //初始化邻接表头指针
    //这里默认顶点编号从0开始,到(Graph->Nv - 1)
    for (V = 0; V < Graph->Nv;V++)
    {
        Graph->G[V].FirstEdge = NULL;
    }

    return Graph;
}

void InsertEdge(struct GNode* Graph,struct ENode* E)
{
    struct AdjNode* NewNode;
    NewNode = (struct AdjNode*)malloc(sizeof(struct AdjNode));
    NewNode->AdjV = E->V2;
    //NewNode->Weight = E->Weight;
    NewNode->Weight = 1;

    //将V2插入V1的表头
    NewNode->Next = Graph->G[E->V1].FirstEdge;
    Graph->G[E->V1].FirstEdge = NewNode;

    //若是无向图,还要插入边<V2,V1>
    NewNode = (struct AdjNode*)malloc(sizeof(struct AdjNode));
    NewNode->AdjV = E->V1;
    //NewNode->Weight = E->Weight;
    NewNode->Weight = 1;

    //将V1插入V2的表头
    NewNode->Next = Graph->G[E->V2].FirstEdge;
    Graph->G[E->V2].FirstEdge = NewNode;
}

struct GNode* BuildGraph()
{
    struct GNode* Graph;
    struct ENode* E;
    int V;
    int Nv, i;

    scanf("%d",&Nv);  //读入顶点的个数
    Graph = CreateGraph(Nv);  //初始化有Nv个顶点,但没有边的图
    scanf("%d",&(Graph->Ne));  //读入边数

    if (Graph->Ne != 0)  //如果有边
    {
        //建立边节点
        E = (struct ENode*)malloc(sizeof(struct ENode));
        
        for (int i = 0;i < Graph->Ne;i++)
        {
            //读入格式为 起点 终点 权重
            //scanf("%d %d %d",&E->V1,&E->V2,&E->Weight);
            scanf("%d %d", &E->V1, &E->V2);
            E->V1--;
            E->V2--;
            InsertEdge(Graph,E);
        }
    }

    //如果顶点有数据的话,读入数据
    //for (int i = 0; i < Graph->Nv;i++)
    //{
    //  scanf("%c",&(Graph->G[i].Data));
    //}

    return Graph;
}

void InitializeVisited(int Nv)
{
    int i = 0;
    for (;i < Nv;i++)
    {
        Visited[i] = false;
    }
}

int SDS_BFS(struct GNode* Graph,int S)
{
    int V = 0;
    int Tail = 0;
    int Last = S;
    int Level = 0;
    int Count = 1;
    struct AdjNode* W = NULL;
    struct QNode* Q = CreateQueue(MaxVerterNum);
    Visited[S] = true; //标记S已经被访问
    AddQ(Q, S);

    while (!IsEmpty(Q))
    {
        V = DeleteQ(Q);
        for (W = Graph->G[V].FirstEdge; W ; W = W->Next)
        {
            if (!Visited[W->AdjV])  
            {
                Visited[W->AdjV] = true;  //标记W->AdjV已经被访问
                //printf("%d.\n",W->AdjV);
                Count++;
                Tail = W->AdjV;  //当前的层尾
                AddQ(Q, W->AdjV);
            }
        }
        if (V == Last)  //如果上一层的最后一个顶点弹出了
        {
            Level++;
            Last = Tail;
        }
        if (Level == 6)
        {
            break;
        }
    }
    return Count;
}

int main()
{
    int count = 0;
    struct GNode* Graph = BuildGraph();
    for (int i = 0;i < Graph->Nv;i++)
    {
        InitializeVisited(Graph->Nv);
        count = SDS_BFS(Graph,i);
        printf("%d: %.2f%%\n",i+1,100.0 * (double)count/(double)Graph->Nv);
    }
    // system("pause");
    return 0;
}

转载于:https://www.cnblogs.com/Manual-Linux/p/11381739.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值