数据结构——六度空间理论验证

一、实验项目要求

1.输入格式:

多组数据输入,每组数据m+1行,第一行有两个数字,n和m,代表着n个人和m组朋友的关系,n个人的编号为1到n,第二行到第m+1行每行包括两个数字a和b,代表着两个人互相认识。

输出格式:

对每个结点输出与该结点距离不超过6的结点数占结点总数的百分比,精确到小数点后2位。每个结节点输出一行,格式为“结点编号:百分比%”。

二、理论分析

六度空间理论的数学模型属于图结构,我们把六度空间理论中的人际关系网络图抽象成一个不带权值的无向图G, 用图G 中的一个顶点表示一个人,两个人 ”认识” 与否,用代表这两个人的顶点之间是否有一条边来表示。这样六度空间理论问题便可描述为:在图 G 中任意两个顶点之间都存在一条路径长度不超过7的路径。 在实际验证过程中,可以通过测试满足要求的数据达到一定的百分比(比如 99.5%) 来进行验证。 这样我们便把待验证六度空间理论问题描述为:在图G 中,任意一个顶点到其余 99.5%以上的顶点都存在一条路径长度不超过 7 的路径。比较简单的一种验证方案是:利用广度优先搜索方法, 对任意一个顶点,通过对图 G的 "7层”遍历,就可以统计出所有路径长度不超过 7 的顶点数 从而得到这些顶点在所有顶点中的所占比例。

三、实现方法

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

#define MaxVertexNum 10000
#define MaxDistance 6
#define DefaultWeight 1
#define QERROR 0

typedef int Vertex;
typedef int WeightType;


typedef struct ENode* PtrToENode;
struct ENode {
    Vertex V1, V2; 
    WeightType Weight;
};
typedef PtrToENode Edge;


typedef struct AdjVNode* PtrToAdjVNode;
struct AdjVNode {
    Vertex AdjV; 
    WeightType Weight;
    PtrToAdjVNode Next;
};


typedef struct Vnode {
    PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];


typedef struct GNode* PtrToGNode;
struct GNode {
    int Nv;
    int Ne;
    bool* visited;
    AdjList G;
};
typedef PtrToGNode LGraph;


typedef struct Node* PtrToNode;
struct Node {
    Vertex Data;
    PtrToNode Next;
};
typedef PtrToNode Position;


struct QNode {
    Position Front, Rear;
    int MaxSize;
};
typedef struct QNode* Queue;

LGraph CreateGraph(int Nv);
void InsertEdge(LGraph Graph, Edge E);
void BFSToSix(LGraph Graph);
int BFS(LGraph Graph, Vertex v);
Queue CreateQueue(int MaxSize);
bool QIsEmpty(Queue Q);
Vertex DeleteQ(Queue Q);
void AddQ(Queue Q, Vertex v);

int main()
{
    
    int N, M;
    LGraph Graph;
    Edge E;

    cin >> N; 
    Graph = CreateGraph(N); 

    cin >> M; 
    E = new ENode;
    for (int i = 0; i < M; i++) {
        cin >> E->V1;
        cin >> E->V2;
        E->Weight = DefaultWeight;
        InsertEdge(Graph, E);
    }

    BFSToSix(Graph);

    return 0;
}

void BFSToSix(LGraph Graph)
{
    int SixVertexNum;
    float percent;
    if (Graph->Nv != 0) {
        for (Vertex v = 1; v < Graph->Nv; v++) {
           
            SixVertexNum = BFS(Graph, v) + 1;
          
            percent = float(SixVertexNum) / float(Graph->Nv - 1);
            cout << v << ":" <<" ";
            cout<<fixed <<setprecision(2)<<percent * 100 << "%" << endl;
           
            for (int i = 0; i < Graph->Nv; i++) Graph->visited[i] = false;
        }
    }
}

int BFS(LGraph Graph, Vertex v)
{
    PtrToAdjVNode w;
    int D = 0;
    int SixVertexNum = 0;
    Queue Q;

    Q = CreateQueue(MaxVertexNum);//创建队列

    Graph->visited[v] = true;
    AddQ(Q, v);
    AddQ(Q, 0);//插入队列中的0,用于表示新的一层的开始
    ++D;
    while (!QIsEmpty(Q)) {
        v = DeleteQ(Q);
        if (v == 0 && D >= MaxDistance) break; //表示层数已超过6
        if (v == 0 && D < MaxDistance) {//层数还未超过6
            AddQ(Q, 0);
            ++D;
            continue;
        }
        for (w = Graph->G[v].FirstEdge; w != NULL; w = w->Next) {

            if (!Graph->visited[w->AdjV]) {
                Graph->visited[w->AdjV] = true;
                AddQ(Q, w->AdjV);
                ++SixVertexNum;
            }
        }
    }
    return SixVertexNum;
}

void InsertEdge(LGraph Graph, Edge E)
{
    PtrToAdjVNode NewNode;

    ++Graph->Ne;

    NewNode = new AdjVNode;
    NewNode->AdjV = E->V2;
    NewNode->Weight = E->Weight;
    NewNode->Next = Graph->G[E->V1].FirstEdge;
    Graph->G[E->V1].FirstEdge = NewNode;


    NewNode = new AdjVNode;
    NewNode->AdjV = E->V1;
    NewNode->Weight = E->Weight;
    NewNode->Next = Graph->G[E->V2].FirstEdge;
    Graph->G[E->V2].FirstEdge = NewNode;
}

LGraph CreateGraph(int N)
{
    LGraph Graph;

    Graph = new GNode;
    Graph->Nv = N + 1; //结点从1开始
    Graph->Ne = 0;
    Graph->visited = new bool[N + 1];

    for (int i = 1; i < Graph->Nv; i++) Graph->visited[i] = false;

    for (int v = 1; v < Graph->Nv; v++) Graph->G[v].FirstEdge = NULL;

    return Graph;
}

Queue CreateQueue(int MaxSize)
{
    Queue Q;
    Q = new QNode;
    Q->Front = Q->Rear = NULL;
    Q->MaxSize = MaxSize;
    return Q;
}

bool QIsEmpty(Queue Q)
{
    return (Q->Front == NULL);
}

void AddQ(Queue Q, Vertex v)
{
    Position NewNode;
    NewNode = new Node;
    NewNode->Data = v;
    NewNode->Next = NULL;

    if (QIsEmpty(Q)) {
        Q->Front = NewNode;
        Q->Rear = NewNode;
    }
    else {
        Q->Rear->Next = NewNode;
        Q->Rear = NewNode;
    }
}

Vertex DeleteQ(Queue Q)
{
    Position FrontNode;
    Vertex FrontData;

    if (QIsEmpty(Q)) {
        return QERROR;
    }
    else {
        FrontNode = Q->Front;
        if (Q->Front == Q->Rear)
            Q->Front = Q->Rear = NULL;
        else
            Q->Front = Q->Front->Next;

        FrontData = FrontNode->Data;
        delete FrontNode;
        return FrontData;
    }

}

四、实验结果分析

 

  • 10
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FineFINE01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值