第七章(6).最小生成树
来源:互联网 发布:淘宝500的充气娃娃图片 编辑:程序博客网 时间:2024/06/08 11:42
//由MiniSpanTree_PRIM()可知Prim算法的时间复杂度为O(n*n),(n为顶点数)与网中的边数无关,因此使用于求边稠密的网的最小生成树。
//而Kruskal算法恰恰相反,它的时间复杂度为O(e*log e),(e为网中边的数目)。它比较适合求边稀疏的网的最小生成树。
#include < stdio.h >
#include < stdlib.h >
#include < string.h >#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2typedef int Status ;
//---------------图的数组(邻接矩阵)存储表示------------------//
#define INFINITY 2147483647 //最大值(无穷大)INT_MAX = 2147483647
#define MAX_VERTEX_NUM 20 //最大顶点个数(vertex顶点)
#define MAX_INFO 20 //关于边的信息的字符串长度
#define MAX_NAME 5 //关于顶点信息的字符串长度typedef int VRType ; //此处考虑无权图
typedef char InfoType ;
typedef char VertexType[MAX_NAME]; //VertexType可以根据实际情况灵活设定类型!int,float,char…typedef enum{ DG , DN , UDG , UDN }GrapKind ; //{有向图(Digraph),有向网(Digraph Network), 无向图(Undigraph),无向网(Undigraph Network)}
typedef struct ArcCell
{
VRType adj ; //VRType是顶点关系类型。对于无权图,用1或0表示相邻否。对于带权图,则为权值类型。
InfoType *info ; //该弧(Arc)相关的信息的指针
} ArcCell , AdjMatrix[ MAX_VERTEX_NUM ][ MAX_VERTEX_NUM ] ;typedef struct
{
VertexType vexs[ MAX_VERTEX_NUM ] ; //顶点向量
AdjMatrix arcs ; //邻接矩阵
int vexnum , arcnum ; //图的当前顶点数和弧树
GrapKind kind ;
} MGraph ;Status InitGraph( MGraph *G ) ;
Status InputInformation( MGraph *G , int i , int j ) ;
Status LocateVex( MGraph G , VertexType u ) ;
Status CreateUDN( MGraph *G ) ;//----------------------------------------------------------------------------------//
typedef struct // 记录从顶点集U到V-U的代价最小的边的辅助数组定义
{
VertexType adjvex ;
VRType lowcost ;
} MinSide[ MAX_VERTEX_NUM ] ;void MiniSpanTree_PRIM( MGraph G , VertexType u ) ;
int minimum( MinSide ms , MGraph G ) ;
#include "head.h"
//--------------------Basic Fuction about the UDN---------------------//
Status InitGraph( MGraph *G )
{
int i , j ;
printf( "Input the number of Vertex and Arc : " ) ;
scanf( "%d %d" , &( *G ).vexnum , &( *G ).arcnum ) ;
printf("Input the vector of %d vex( %d char ): \n" , ( *G ).vexnum , MAX_NAME ) ;
for( i = 0 ; i < ( *G ).vexnum ; ++ i ) //构造顶点向量 Input:a b c d …(输入字符处理)
{
scanf( "%s" , ( *G ).vexs[ i ] ) ; //访存错误,因为无内存。刚开始定义typedef char* VertexType; 所以( *G ).vexs[ i ]只是一个没有空间的指针
}
for( i = 0 ; i < ( *G ).vexnum ; ++ i ) //初始化邻接矩阵
{
for( j = 0 ; j < ( *G ).vexnum ; ++ j )
{
( *G ).arcs[ i ][ j ].adj = INFINITY ; //{adj , info}网 INFINITY等效于无穷大
( *G ).arcs[ i ][ j ].info = NULL ;
}
}return OK ;
}Status InputInformation( MGraph *G , int i , int j )
{
char s[ MAX_INFO ] , *info ;
int w ;
printf("请输入该边的相关信息(%d个字符): ", MAX_INFO ) ;
gets( s );
w = strlen( s ) ;
if( w )
{
info = ( char * )malloc( ( w + 1 ) * sizeof( char ) ) ;
strcpy( info , s ) ;
( *G ).arcs[ i ][ j ].info = info ;
}
return OK ;
}Status LocateVex( MGraph G , VertexType u ) //若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
{
int i ;
for( i = 0 ; i < G.vexnum ; ++ i )
{
if( strcmp( u , G.vexs[ i ] ) == 0 )
return i ;
}
return EOF ; //EOF means -1 .
}Status CreateUDN( MGraph *G ) //构造无向网*G
{
int i , j , k , w ;
int IncInfo ;
VertexType va , vb ;
// va = vb = NULL ; //typedef char VertexType[MAX_NAME];后,va,vb实际上是一个数组名,有空间!而指针则需要初始化
InitGraph( G ) ;
printf( "It's there any information for arc?( 1 means yes ): " ) ;
scanf( "%d" , &IncInfo ) ;
printf( "请输入%d条弧的边尾、边头以及权值: \n" , ( *G ).arcnum ) ;for( k = 0 ; k < ( *G ).arcnum ; ++ k ) //构造邻接矩阵
{
scanf( "%s%s%d%*c", va , vb , &w ) ; //%*c吃掉回车符 //输入一条边依附的顶点及权值 (va, vb输入字符处理)
i = LocateVex( *G , va ) ;
j = LocateVex( *G , vb ) ;
( *G ).arcs[ i ][ j ].adj = w ; //弧< va , vb >的权值
if( IncInfo ) //若弧含有相关信息,则输入
{
InputInformation( G , i , j ) ;
}
( *G ).arcs[ j ][ i ] = ( *G ).arcs[ i ][ j ] ; // adj and info.
}
( *G ).kind = UDN ; //此处UDN为3,这是在enun中决定的!
return OK ;
}//-----------------Function for MinSpanTree-------------------------------//
void MiniSpanTree_PRIM( MGraph G , VertexType u )//用Prim算法从顶点u出发构造网G的最小生成树T,输出T的各条边.
{
int k , i , j ;
MinSide closedge ;k = LocateVex( G , u ) ;
for( j = 0 ; j < G.vexnum ; ++ j ) //初始化辅助数组
{
if( j != k )
{
strcpy( closedge[ j ].adjvex , u ) ;
closedge[ j ].lowcost = G.arcs[ k ][ j ].adj ;
}
}
closedge[ k ].lowcost = 0 ; //初始,U = { u } ;for( i = 1 ; i < G.vexnum ; ++ i ) //选择其余的G.vexnum - 1 个顶点.
{
k = minimum( closedge , G ) ; //求出T的下一个结点:第K顶点
printf( "%s---------------->%s\n" , closedge[ k ].adjvex , G.vexs[ k ] ) ;
closedge[ k ].lowcost = 0 ; //将第K个顶点并入U集for( j = 0 ; j < G.vexnum ; ++ j )
{
if( G.arcs[ k ][ j ].adj < closedge[ j ].lowcost ) //新顶点并入U后重新选择最小边
{
strcpy( closedge[ j ].adjvex , G.vexs[ k ] ) ;
closedge[ j ].lowcost = G.arcs[ k ][ j ].adj ;
}
}
}
}int minimum( MinSide ms , MGraph G ) //求closedge.lowcost的最小值
{
int j , k , min , i = 0 ;while( !ms[ i ].lowcost ) //排除等于0的,即属于集合U的。
++ i ;min = ms[ i ].lowcost ; //第一个不为0的值.
k = i ;
for( j = i + 1 ; j < G.vexnum ; ++ j )
{
if( ms[ j ].lowcost > 0 && min > ms[ j ].lowcost ) //ms[ j ].lowcost仅仅为了程序的健壮性。
{
min = ms[ j ].lowcost ;
k = j ;
}
}
return k ;
}int main( )
{
MGraph G ;
// closedge[ 0 ].lowcost = 10 ; //悲催!无点引用!不过可以执行通过,应该是编译器的原因。
// printf( "%d\n" , closedge[ 0 ].lowcost ) ;CreateUDN( &G ) ;
MiniSpanTree_PRIM( G , G.vexs[ 0 ] ) ; //Oh! So Cool!return 0 ;
}
- 第七章(6).最小生成树
- 大话数据结构 code 第七章 05最小生成树_Prim
- 大话数据结构 code 第七章 06最小生成树_Kruskal
- 第七章 图(最小生成树之prime算法和 kruskal算法)
- 数据结构编程笔记二十:第七章 图 最小生成树算法的实现
- 最小生成树(Prim)(普利姆最小生成树)
- 最小方差生成树(最小生成树)
- 最小生成树(prim)
- 最小生成树(Kruskal)
- HDU1863(最小生成树)
- 最小生成树(转)
- poj3925(最小生成树)
- 最小生成树(模板)
- 最小生成树(Kruskal)
- 最小生成树(Prim)
- Outlets(最小生成树)
- prim(最小生成树)
- poj2031(最小生成树)
- 第六章(7).哈夫曼树及其应用
- 第七章(1).图的数组(邻接矩阵)存储表示
- 第七章(2).图的邻接表存储表示
- 第七章(3).图的十字链表存储表示
- 第七章(5).非连通图的生成森林
- 第七章(6).最小生成树
- 第七章(7).关结点和重连通分量
- 第七章(8).拓扑排序
- 第七章(9).关键路径
- 第七章(10).单源最短路径
- synchronized 关键字最佳实践
- 第七章(11).每对顶点间的最短路径
- 第九章(1).顺序查找以及折半查找
- 自我摸索阶段