思想是构建一个点的集合和一个边的集合,点集合是点,一个点标记和一个记录该点与其他点连线的次数。边集合记录两点的连线,权值的大小和标记。任何构建相应的方法。方法中的查找最小树 先对边集合按从小到大的排序,在查找过程中当两点都为被标记是则标记该边集合。当标记边集合等于点集合总数减一时,则跳出。当标记的边集合小于点集合总数减一时,则找出一个点与其他点连线的次数最多的点,然后找出未出现的该点所在边集合的最小标记输出。
头文件:
struct tu{
struct tujiedian *zu;
struct tulianxi *biao;
int Zcount;
int Bcount;
};
struct tujiedian{
char info;
int jihao;
int shu;
};
struct tulianxi{
int head;
int tall;
int length;
int fuhao;
};
struct tu *tu_init();
void add_tujiedian_init(struct tu *s,char infos);
void add_tulianxi_init(struct tu *s,int head1,int tall1,int length1);
void tuzongxiangbianli_init(struct tu *s);
方法体的扩写:
#include<stdio.h>
#include<stdlib.h>
#include"tutou.h"
struct tu *tu_init(){//申请相应的空间
struct tu *s;
s=(struct tu *)malloc(sizeof(struct tu));
s->zu=(struct tujiedian )malloc(20sizeof(struct tujiedian));
s->biao=(struct tulianxi )malloc(20sizeof(struct tulianxi));
s->Zcount=0;
s->Bcount=0;
return s;
}
void add_tulianxi_init(struct tu *s,int head1,int tall1,int length1){//边集合的添加
s->biao[s->Bcount].head=head1;
s->biao[s->Bcount].tall=tall1;
s->biao[s->Bcount].length=length1;
s->biao[s->Bcount].fuhao=0;
s->Bcount++;
return;
}
void add_tujiedian_init(struct tu *s,char infos){//点集合的添加
s->zu[s->Zcount].info=infos;
s->zu[s->Zcount].jihao=0;
s->zu[s->Zcount].shu=0;
s->Zcount++;
return;
}
void tuzongxiangbianli_init(struct tu *s){//查找最小树
int i,j,h,w,q,p;
p=0;
//对边进行排序
///
for(i=0;i<s->Bcount-1;i++){
h=i;
for(j=i+1;j<s->Bcount;j++){
if(s->biao[h].length>s->biao[j].length){
h=j;
}
}
s->biao[s->Bcount]=s->biao[i];
s->biao[i]=s->biao[h];
s->biao[h]=s->biao[s->Bcount];
}
/
//找出一个点与其他点连线的次数最多的点
/
for(i=0;i<s->Zcount-1;i++){
q=0;
for(j=0;j<s->Bcount;j++){
if(i==s->biao[j].head||i==s->biao[j].tall){
q++;
}
}
s->zu[i].shu=q;
}
j=0;
for(i=1;i<s->Zcount;i++){
if(s->zu[i].shu>s->zu[j].shu){
j=i;
}
}
//
在查找过程中当两点都为被标记是则标记该边集合。当标记边集合等于点集
//合总数减一时,则跳出
//
for(h=0;h<s->Bcount;h++){
if(s->zu[s->biao[h].head].jihao!=1||s->zu[s->biao[h].tall].jihao!=1){
s->biao[h].fuhao=1;
p++;
s->zu[s->biao[h].head].jihao=1;
s->zu[s->biao[h].tall].jihao=1;
}
if(p==s->Zcount-1){break;}
}
//
/
///当标记的边集合小于点集合总数减一时,则找出一个点与其他点连线的次数
///最多的点,然后找出未出现的该点所在边集合的最小标记输出。
///
if(p!=s->Zcount-1){
for(h=p;h<s->Bcount;h++){
if(s->biao[h].head==j||s->biao[h].tall==j){
s->biao[h].fuhao=1;
p++;
}
if(p==s->Zcount-1){break;}
}
}
//
/
///输出标记的边集合
//
w=0;
for(h=0;h<s->Bcount;h++){
if(s->biao[h].fuhao==1){
printf("%c-%c length=%d\n",s->zu[s->biao[h].head].info,s->zu[s->biao[h].tall].info,s->biao[h].length);
w+=s->biao[h].length;
}
}
printf("最小路径:length=%d\n",w);
return;
}
/
加粗样式
main函数:
#include<stdio.h>
#include<stdlib.h>
#include"tutou.h"
int main(int argc,char **argv){
struct tu *list=NULL;
list=tu_init();
add_tujiedian_init(list,‘a’);
add_tujiedian_init(list,‘b’);
add_tujiedian_init(list,‘c’);
add_tujiedian_init(list,‘d’);
add_tujiedian_init(list,‘e’);
add_tujiedian_init(list,‘f’);
add_tulianxi_init(list,0,1,1);
add_tulianxi_init(list,0,2,2);
add_tulianxi_init(list,0,3,3);
add_tulianxi_init(list,1,2,3);
add_tulianxi_init(list,1,3,0);
add_tulianxi_init(list,2,3,2);
add_tulianxi_init(list,2,4,1);
add_tulianxi_init(list,2,5,3);
add_tulianxi_init(list,3,5,2);
add_tulianxi_init(list,4,5,5);
tuzongxiangbianli_init(list);
return 0;
}