实验报告
实验内容
输出指定无向图的最小生成树。
实验环境
Windows10x64、VS 2019(或DevC++ 5)
算法描述
调用关系:
源程序清单
SimpleGrap.cpp:
#include<stdio.h>
#include<stdlib.h>
#include"Graphics.h"
void Print(_* _0){
printf("规模:%d\n", _0->Size); {
printf("┏");for (int x = 0; x < _0->Size; x++) printf(" ");printf("┓\n");
}
for (int y = 0; y < _0->Size; y++){
printf("┃");
for (int x = 0; x < _0->Size; x++) printf("%3d ", _0->Data[x][y]);
printf("┃\n");
}{
printf("┗");for (int x = 0; x < _0->Size; x++) printf(" ");printf("┛\n");
}
}
_ CreateMatrix(){
//创建邻接矩阵
printf("\n键入图规模:");
N len = *IntScanner(0);
len = len > 0 ? len : 0;
printf("规模为%d。\n\n", len);
printf("输入矩阵,其中\"0\"表示无路径:\n");
_ _0 = *(_*)malloc(sizeof(_));
_0.Size = len;
if (len <= 0) return _0;
Npp X = (Npp)malloc(len * sizeof(Np));
for (int i = 0; i < len; i++)X[i] = (Np)malloc(len * sizeof(N));
_0.Data = X;
for (int y = 0; y < len; y++){
for (int x = 0; x < len; x++){
printf("当前键入一个整数作为矩阵第%d行%d列值:", y, x);
N push = *IntScanner(0);
printf("检测到键入的值为%d\n", push);
if (push <= 0) push = 0;
_0.Data[x][y] = push;
}
}printf("矩阵输入成功。\n");
/*画矩阵*/Print(&_0); /*画完了*/
return _0;
}
bool IsUcg(_* _0){
if (_0 == NULL || _0->Size <= 0) return false;//NULL检查
for (int n = 0; n < _0->Size; n++){
//自回路检查
if (_0->Data[n][n] != 0) return false;
}
for (int n = 0; n < _0->Size; n++){
//无向性检查
bool b = true;
for (int i = 0; i < _0->Size; i++){
if (_0->Data[n][i] != _0->Data[i][n]) return false;//权值不等
if (_0->Data[n][i] != 0) b = false;//连通
}if (b) return false;
}return true;
}
bool DfsCore(_* _0, int Now, bool* vstd) {
vstd[Now] = true;//这个顶点已经被访问过了
bool b = true;
//printf("%d ", Now);
int c = 0;
for (int i = 0; i < _0->Size; i++){
if (_0->Data[Now][i] != 0) {
if (!vstd[i]) {
b = b && DfsCore(_0, i, vstd);
}else{
c++;
if (c > 1) b = false;
}
}
}return b;
}
bool Dfs(_* _0, int Now){
if (_0 == NULL || _0->Size <= 0 || _0->Data == NULL){
//是无向连通简单图
//printf("非无向连通简单图。\n\n");
return false;
}
bool* np = (bool*)malloc(_0->Size * sizeof(bool));
for (int i = 0; i < _0->Size; i++)np[i] = 0;
bool b = true;
b = DfsCore(_0, Now, np);
return b;
}
_ Prim(_ grap)
{
_ _0 = *(_*)malloc(sizeof(_));
_0.Size = grap.Size;
if (_0.Size > 0){
//无向图是对称的,所以出度入度值不去区分
Npp X = (Npp)malloc(grap.Size * sizeof(Np));
for (int i = 0; i < grap.Size; i++)X[i] = (Np)malloc(grap.Size * sizeof(N));
_0.Data = X;
for (int y = 0; y < grap.Size; y++)//赋初值
for (int x = 0; x < grap.Size; x++)_0.Data[x][y] = 0;
int count = 0;
if (IsUcg(&grap)) {
//是无向连通简单图
int* vstd = (int*)malloc(sizeof(int) * grap.Size);
int vstdTop = 0;
vstd[vstdTop++] = 0;
for (int maxlooptimes=0;maxlooptimes<32767;maxlooptimes++)/*死循环,但不完全死*/{
int min = 32767;
int start=0; int end=0;//权最小的路径为<start,end>
for (int tin = 0; tin < vstdTop; tin++){
for (int nowi = 0; nowi < grap.Size; nowi++){
//选择权最小的路径
if (min>=grap.Data[vstd[tin]][nowi]&&grap.Data[vstd[tin]][nowi]>0) {
min = grap.Data[vstd[tin]][nowi];
end = nowi;
start = vstd[tin];
}
}
}
grap.Data[start][end]=0;grap.Data[end][start]=0; //无论是不是树,访问过的路径就要删
if (min >= 32767) min = 0;
_0.Data[start][end] = min; _0.Data[end][start] = min; //预添加路径
if (Dfs(&_0, start)) {
//是否为树
vstd[vstdTop++] = end; count++;
}else{
_0.Data[start][end] = 0; _0.Data[end][start] = 0; //撤销预添加
}if (IsUcg(&_0)&&count>=_0.Size) break;//添加了所有顶点,跳出
}
}
}return _0;
}
Head.h:
#pragma once
typedef int N;
typedef int* Np;
typedef int** Npp;
struct _{
Npp Data;
N Size;
};
Np IntScanner(N);
_ CreateMatrix();
_ Prim(_);
void Print(_*);
bool Dfs(_*, int);
Main.cpp:
#include<stdio.h>
#include<stdlib.h>
#include"Graphics.h"
int main(){
_ l = CreateMatrix();
_ l1 = Prim(l);
printf("最小生成树:\n");
Print(&l1);
system("pause");return 0;
}