idk why these stuffs get stashed for so long and I didn't ever commit them

This commit is contained in:
2025-11-06 09:43:54 +08:00
parent 5dbdfef1a1
commit e01c041259
232 changed files with 22806 additions and 1256 deletions

View File

@@ -0,0 +1,217 @@
#include<string>
#include "LinkQueue.h"
#include "Mgraph.h"
#include <iostream>
using namespace std;
const MAX_ARCNUM=50;
// 最小生成树
//算法6.18 Prim算法
struct CEdge // 候选边存储
{
int adjvex; // U中集合点
int lowcost; // 最小边的权值
};
int minEdge(CEdge closeEdge[],int n)
{
int i, k=0;
int min = INF;
for ( i=0; i<n; i++) //求出与U权值最小的点 权值为0的代表在集合U
{
if (closeEdge[i].lowcost != 0 && closeEdge[i].lowcost<min)
{
min = closeEdge[i].lowcost;
k = i;
}
}
return k;
}
template<class DT>
bool Prim_MST(MGraph<DT> G, DT v) // 从顶点v开始计算的最小生成树
{
CEdge closeEdge[MAX_VEXNUM];
int i,j,k,mincost = 0;
k=LocateVex(G,v);
if(k==-1) // 顶点不存在
{
cout<<"顶点不存在!"<<endl;
return false;
}
for (i = 0; i < G.vexnum; i++) // 辅助数组初始化
if(i!=k)
{
closeEdge[i].adjvex = k; // u中的点
closeEdge[i].lowcost = G.arcs[k][i];
}
closeEdge[k].lowcost=0; // 初始 U={v}
cout << "\n Prim最小生成树的边:"<< endl;
for (i = 1; i < G.vexnum; i++) // 选择其余G.vexnum-1个顶点
{
k=minEdge(closeEdge,G.vexnum); // 输出选择的权值最小的边
cout << "(" <<G.vexs[closeEdge[k].adjvex]<< "," << G.vexs[k]
<<"): "<<closeEdge[k].lowcost<<endl;
mincost+=closeEdge[k].lowcost;
closeEdge[k].lowcost=0;
for (j = 0; j<G.vexnum; j++) // 更新最小边
{
if (closeEdge[j].lowcost != 0 && G.arcs[k][j]<closeEdge[j].lowcost)
{
closeEdge[j].adjvex = k;
closeEdge[j].lowcost= G.arcs[k][j];
}
}
}
cout << "\n Prim最小生成树权值之和:" << mincost << endl;
return true;
}
// Kruskal算法
struct Edge{ // 存储边的信息
int u,v;
int cost;
};
//Edge edge[MAX_ARCNUM];
void Sort(Edge edge[],int n) // 冒泡排序
{
int i,j;
//int k;
Edge temp;
bool exchange;
for(i=0,exchange=true;i<n-1 && exchange; i++) // 一趟排序工作如下:
{
exchange=false; // 1.设置交换标志初值为无交换
for(j=0;j<n-i-1;j++) // 2.从表首开始两两比较
{
if (edge[j].cost>edge[j+1].cost) // 2.1相邻元素逆序,互换位置
{
temp=edge[j];edge[j]=edge[j+1];edge[j+1]=temp; // R[j]<-->R[j+1]
exchange=true; // 2.2 交换标志改为true
}
}
}
}
int parent[MAX_VEXNUM];
void Connect(int &x,int &y) // 连通分量标识
{
if(x<y)
y=x;
else
x=y;
}
//算法6.19 克鲁斯卡尔Kruskal算法
template <class DT>
bool Kruskal_MST(MGraph<DT> G) // 返回生成代价
{
int mincost=0,Num_Edge=0;
char u,v;
int i,j,k=0;
Edge edge[MAX_ARCNUM];
for(i=0;i<G.vexnum;i++) // 从邻接矩阵获取边信息
for(j=0;j<G.vexnum;j++)
{
if(i<j && G.arcs[i][j]!=INF)
{
edge[k].u=i; // 存储边的信息
edge[k].v=j;
edge[k].cost=G.arcs[i][j];
k++;
}
}
Sort(edge,G.arcnum); // 边排序
for(i=0;i<G.vexnum;i++) // 连通分量初始化
{
parent[i]=i;
}
cout << "\n Kruskal 最小生成树的边:"<< endl;
for(i=0;i<G.arcnum;i++) // 从小到考察选取n-1条边
{
j=edge[i].u;
k=edge[i].v;
int vx1=parent[j]; // 获取边起点、终点所在的连通分量标志
int vx2=parent[k];
if(vx1!=vx2) // 如果不属于同一个连通分量, 生成边
{
GetVex(G,j,u);
GetVex(G,k,v);
cout<<"("<<u<<","<<v<<"):"<<G.arcs[j][k]<<endl;
Connect(parent[j],parent[k]); // 合并连通分量
mincost+=edge[i].cost;
Num_Edge++; // 已找到的边数+1
if(Num_Edge==G.vexnum-1)
break;
}
}
if(Num_Edge!=G.vexnum-1) // 判断最小生成树的查找情况
{
cout<<"非连通图,无最小生成树!"<<endl;
return false;
}
else
{
cout<<"\nKruskal最小生树权值为"<<mincost<<endl;
return true;
}
}
void DispMenu()
{
cout<<"\n 请选择你要的操作"<<endl;
cout<<" 1. 建立无向网"<<endl;
cout<<" 2. Prinmt算法"<<endl;
cout<<" 3. Kruskal算法"<<endl;
cout<<" 4. 显示网"<<endl;
cout<<" 0. 退出"<<endl;
}
bool visited[MAX_VEXNUM]={false};
void main()
{
char v;
//int k,weight;
MGraph<char> G;
int choice;
do
{
DispMenu();
cin>>choice;
switch(choice)
{
case 1: // 创建无向网
CreateUDN(G);
cout<<endl;
cout<<"创建的网为:"<<endl;
DispG(G);
break;
case 2: // Prinmt算法
cout<<"请输入起始计算顶点: ";
cin>>v;
Prim_MST(G,v);
break;
case 3: // Kruskal算法
Kruskal_MST(G);
cout<<endl;
break;
case 4: // 显示网
DispG(G);
cout<<endl;
break;
case 0:
cout<<"结束运行Bye-Bye!"<<endl;
break;
default:
cout<<"选择不合理,请重选!"<<endl;
}//case
}while(choice!=0);
}//main