结果截图
问题描述
随机创建一个100个顶点,大约2000条边的有向图以及大约1000条边的无向图,并可以输出每个点的入度和出度(使用邻接表表示)
问题分析
本问题我通过首先创建一个随机邻接矩阵,并将其存入文件中,然后从文件中读取信息建立图结构(与ACM题目吻合)
难点在于图的数据结构(我使用C/C++进行实现)
源代码
#pragma once
#include<iostream>
#include<ctime>
#include<cmath>
#include <cstdlib>
using namespace std;
typedef int Vertex;
struct Node;
typedef struct Node *PtrToNode, *List;
struct Node {
Vertex adjvex;
int weight;
PtrToNode next;//指向下一个结点的指针
};
struct VertexRecord {
//ElementType Element;
int in_degree;//入度
int out_degree;//出度
List adjto;//指向第一个邻接结点的指针
};
struct GraphRecord {
int vexnum;
struct VertexRecord *vertices;//数组
};
typedef struct GraphRecord *Graph;
const int VertexNum = 20;
const int INF = 0x3f3f3f3f;
void CreateRandomDirectGraph();//生成有向图的矩阵
Graph CreateDirectGraph();//根据随机产生的有向图矩阵生成有向图的链表表示
void CreateRandomUndirectGraph();//生成有向图的矩阵
Graph CreateUndirectGraph();//根据随机产生的有向图矩阵生成有向图的链表表示
void print_graph(Graph G);//打印图结构
void print_VertexDegree(Graph G);//打印图各顶点的度数
void print_EdgeWeight(Graph G);//打印图的各边的权值
int matrix[VertexNum + 1][VertexNum + 1];
double random(double start, double end);
double random(double start, double end)//产生start~end之间的随机数
{
return start + (end - start)*rand() / (RAND_MAX + 1.0);
}
void CreateRandomDirectGraph()
{
FILE *fp;
fp = fopen("F:/C++/DirectGraph_100.txt", "w");
srand(unsigned(time(0)));
int x;
for (int i = 0; i < VertexNum;i++) {
for (int j = 0; j < VertexNum; j++) {
x = (int)random(0, 20);//产生0~20的随机数,如果小于5则有边(题目要求20个顶点,大约100条边)
if (i!=j&&x < 5) matrix[i][j] = 1;
else matrix[i][j] = 0;
fprintf(fp,"%d\n", matrix[i][j]);
}
}
fclose(fp);
}
Graph CreateDirectGraph() {
FILE *fp;
fp = fopen("F:/C++/DirectGraph_100.txt", "r");
//图的初始化
Graph G;
PtrToNode ptr;
G = (struct GraphRecord*)malloc(sizeof(struct GraphRecord));
G->vexnum = VertexNum;
G->vertices = (struct VertexRecord*)malloc(sizeof(struct VertexRecord)*VertexNum);
for (int i = 0; i < VertexNum; i++) {
G->vertices[i].adjto = NULL;
G->vertices[i].in_degree = 0;
G->vertices[i].out_degree = 0;
}
int flag;
srand(unsigned(time(0)));
int Edge_weight;
//图的构建
for (int i = 0; i < VertexNum; i++) {
for (int j = 0; j < VertexNum; j++) {
fscanf(fp, "%d", &flag);
if (flag) {
Edge_weight = (int)random(1, 20);//随机产生边的权值
ptr = (struct Node*)malloc(sizeof(struct Node));
ptr->adjvex = j;
ptr->weight = Edge_weight;
G->vertices[i].out_degree++;//出度
G->vertices[j].in_degree++;//入度
ptr->next = G->vertices[i].adjto;
G->vertices[i].adjto = ptr;
}
}
}
fclose(fp);
return G;
}
void CreateRandomUndirectGraph()//与creatRandomDirectGrap方法一致,随机产生邻接矩阵
{
FILE *fp;
fp = fopen("F:/C++/UndirectGraph_100.txt", "w");
srand(unsigned(time(0)));
int x;
for (int i = 0; i < VertexNum; i++) {
for (int j = 0; j < VertexNum; j++) {
x = (int)random(0, 20);
if (i != j&&x < 5) matrix[i][j] = 1;
else matrix[i][j] = 0;
fprintf(fp, "%d\n", matrix[i][j]);
}
}
fclose(fp);
}
Graph CreateUndirectGraph() {
FILE *fp;
fp = fopen("F:/C++/UndirectGraph_100.txt", "r");
//图的初始化
Graph G;
PtrToNode ptr1, ptr2;
G = (struct GraphRecord*)malloc(sizeof(struct GraphRecord));
G->vexnum = VertexNum;
G->vertices = (struct VertexRecord*)malloc(sizeof(struct VertexRecord)*VertexNum);
for (int i = 0; i < VertexNum; i++) {
G->vertices[i].adjto = NULL;
G->vertices[i].in_degree = 0;
G->vertices[i].out_degree = 0;
}
int flag;
srand(unsigned(time(0)));
int Edge_weight;
//图的构建
for (int i = 0; i < VertexNum; i++) {
for (int j = i + 1; j < VertexNum; j++) {
fscanf(fp, "%d", &flag);
if (flag) {
Edge_weight = (int)random(1, 20);//随机产生边的权值
ptr1 = (struct Node*)malloc(sizeof(struct Node));
ptr1->adjvex = j;
ptr1->weight = Edge_weight;
G->vertices[i].out_degree++;//出度
G->vertices[j].in_degree++;//入度
ptr1->next = G->vertices[i].adjto;
G->vertices[i].adjto = ptr1;
ptr2 = (struct Node*)malloc(sizeof(struct Node));
ptr2->adjvex = i;
ptr2->weight = Edge_weight;
G->vertices[j].out_degree++;//出度
G->vertices[i].in_degree++;//入度
ptr2->next = G->vertices[j].adjto;
G->vertices[j].adjto = ptr2;
}
}
}
fclose(fp);
return G;
}
void print_graph(Graph G) {//打印图结构
PtrToNode ptr;
int count = 0;
for (int i = 0; i < G->vexnum; i++) {
printf("顶点%d:", i);
ptr = G->vertices[i].adjto;
while (ptr != NULL) {
printf(" %d", ptr->adjvex);
ptr = ptr->next;
count++;
}
printf("\n");
}
printf("顶点的数量为:%d,有向边的数量(一条无向边按照两条有向边计算)为:%d\n", VertexNum, count);
}
void print_VertexDegree(Graph G) {
for (int i = 0; i < G->vexnum; i++) {
printf("顶点%d的入度为:%d,出度为:%d\n", i, G->vertices[i].in_degree, G->vertices[i].out_degree);
}
}
void print_EdgeWeight(Graph G) {
PtrToNode ptr;
for (int i = 0; i < G->vexnum; i++) {
ptr = G->vertices[i].adjto;
while (ptr != NULL) {
printf("边<%d,%d>的权值为:%d\n", i,ptr->adjvex, ptr->weight);
ptr = ptr->next;
}
}
}
int main() {
//有向图的随机生成(20个顶点,100左右的边,可以进行修改)
//CreateRandomDirectGraph();
//Graph G = CreateDirectGraph();
//无向边的随机生成(20个顶点,50左右的边)
CreateRandomUndirectGraph();
Graph G = CreateUndirectGraph();
print_graph(G);//打印图
printf("打印各顶点入度和出度:\n");
print_VertexDegree(G);//打印顶点度数
printf("打印每条边的权值:\n");
print_EdgeWeight(G);//打印边权
return 0;
}
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。