• 最小生成树(Kruskal实现)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <stdbool.h>
      5 
      6 #define MaxVertexNodeNumSize 1000
      7 #define MaxVertexNodeNameSize 100
      8 
      9 struct VertexBodyNode
     10 {
     11     char VertexName[MaxVertexNodeNameSize];
     12     int ArcWeight;
     13     int VertexIndex;
     14     struct VertexBodyNode *Next;
     15 };
     16 
     17 struct VertexHeadNode
     18 {
     19     char VertexName[MaxVertexNodeNameSize];
     20     int VertexWeight;
     21     struct VertexBodyNode *Next;
     22 };
     23 
     24 struct _Graph
     25 {
     26     struct VertexHeadNode VertexHeadNodeList[MaxVertexNodeNumSize];
     27     int ArcNum,VertexNum;
     28 };
     29 
     30 int VertexName2Index(struct _Graph *UnsignedGraph,char *VName)
     31 {
     32     int i;
     33     for(i = 0; i < UnsignedGraph -> VertexNum; i ++)
     34     {
     35         if(strcmp(UnsignedGraph -> VertexHeadNodeList[i].VertexName,VName)==0)
     36         {
     37             return i;
     38         }
     39     }
     40     return -1;
     41 }
     42 
     43 void AddOneArc(struct _Graph *UnsignedGraph,int ArcIndex_1,int ArcIndex_2,int AWeight)
     44 {
     45     struct VertexBodyNode *BNode_1 = malloc(sizeof(struct VertexBodyNode));
     46     struct VertexBodyNode *BNode_2 = malloc(sizeof(struct VertexBodyNode));
     47 
     48     strcpy(BNode_1 -> VertexName,UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].VertexName);
     49     strcpy(BNode_2 -> VertexName,UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].VertexName);
     50     BNode_1 -> ArcWeight = AWeight;
     51     BNode_2 -> ArcWeight = AWeight;
     52     BNode_1 -> VertexIndex = ArcIndex_1;
     53     BNode_2 -> VertexIndex = ArcIndex_2;
     54     BNode_1 -> Next = BNode_2 -> Next = NULL;
     55 
     56     struct VertexBodyNode *TmpPointer;
     57     TmpPointer = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
     58     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
     59     {
     60         TmpPointer = TmpPointer -> Next;
     61     }
     62     if(TmpPointer==NULL)
     63     {
     64         UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next = BNode_2;
     65     }
     66     else
     67     {
     68         TmpPointer -> Next = BNode_2;
     69     }
     70 
     71     TmpPointer = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
     72     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
     73     {
     74         TmpPointer = TmpPointer -> Next;
     75     }
     76     if(TmpPointer==NULL)
     77     {
     78         UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next = BNode_1;
     79     }
     80     else
     81     {
     82         TmpPointer -> Next = BNode_1;
     83     }
     84 }
     85 
     86 void DeleteOneArc(struct _Graph *UnsignedGraph,int ArcIndex_1,int ArcIndex_2)
     87 {
     88     struct VertexBodyNode *TmpPointer_1,*TmpPointer_2;
     89 
     90     TmpPointer_1 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
     91     TmpPointer_2 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
     92 
     93     while(TmpPointer_2!=NULL && TmpPointer_2->VertexIndex!=ArcIndex_2)
     94     {
     95         TmpPointer_1 = TmpPointer_2;
     96         TmpPointer_2 = TmpPointer_2 -> Next;
     97     }
     98 
     99     if(TmpPointer_2==NULL)
    100     {
    101         return ;
    102     }
    103     else if(TmpPointer_1 == TmpPointer_2)
    104     {
    105         UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next = NULL;
    106         free(TmpPointer_2);
    107     }
    108     else
    109     {
    110         TmpPointer_1 -> Next = TmpPointer_2 -> Next;
    111         free(TmpPointer_2);
    112     }
    113 
    114     TmpPointer_1 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
    115     TmpPointer_2 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
    116 
    117     while(TmpPointer_2!=NULL && TmpPointer_2->VertexIndex!=ArcIndex_1)
    118     {
    119         TmpPointer_1 = TmpPointer_2;
    120         TmpPointer_2 = TmpPointer_2 -> Next;
    121     }
    122 
    123     if(TmpPointer_2==NULL)
    124     {
    125         return ;
    126     }
    127     else if(TmpPointer_1 == TmpPointer_2)
    128     {
    129         UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next = NULL;
    130         free(TmpPointer_2);
    131     }
    132     else
    133     {
    134         TmpPointer_1 -> Next = TmpPointer_2 -> Next;
    135         free(TmpPointer_2);
    136     }
    137 }
    138 
    139 struct _Graph *UGCreat(int ArcSum,int VertexSum)
    140 {
    141     int i,j;
    142     struct _Graph *UnsignedGraph = malloc(sizeof(struct _Graph));
    143     UnsignedGraph -> ArcNum = ArcSum;
    144     UnsignedGraph -> VertexNum = VertexSum;
    145 
    146     for(i = 0; i < VertexSum; i ++)
    147     {
    148         scanf("%s %d",UnsignedGraph -> VertexHeadNodeList[i].VertexName,&UnsignedGraph -> VertexHeadNodeList[i].VertexWeight);
    149     }
    150 
    151     for(i = 0; i < VertexSum; i ++)
    152     {
    153         UnsignedGraph -> VertexHeadNodeList[i].Next = NULL;
    154     }
    155 
    156     for(i = 0; i < ArcSum; i ++)
    157     {
    158         char Arc_1[MaxVertexNodeNameSize];
    159         char Arc_2[MaxVertexNodeNameSize];
    160         int ArcIndex_1;
    161         int ArcIndex_2;
    162         int ArcWeight;
    163 
    164         scanf("%s %s %d",Arc_1,Arc_2,&ArcWeight);
    165 
    166         ArcIndex_1 = VertexName2Index(UnsignedGraph,Arc_1);
    167         ArcIndex_2 = VertexName2Index(UnsignedGraph,Arc_2);
    168 
    169         AddOneArc(UnsignedGraph,ArcIndex_1,ArcIndex_2,ArcWeight);
    170     }
    171     return UnsignedGraph;
    172 }
    173 
    174 void Travel(struct _Graph *UnsignedGraph)
    175 {
    176     char StartingPoint[MaxVertexNodeNameSize];
    177     char OverPoint[MaxVertexNodeNameSize];
    178 
    179     printf("Input start and over
    ");
    180     scanf("%s %s",StartingPoint,OverPoint);
    181 
    182     int StartIndex = VertexName2Index(UnsignedGraph,StartingPoint);
    183     int OverIndex = VertexName2Index(UnsignedGraph,OverPoint);
    184 
    185     struct VertexBodyNode *TmpPointer;
    186     TmpPointer = UnsignedGraph -> VertexHeadNodeList[StartIndex].Next;
    187     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
    188     {
    189         if(OverIndex==TmpPointer -> VertexIndex)
    190         {
    191             printf("Distance:%d GetVertexPointSum:%d",TmpPointer->ArcWeight
    192                    ,UnsignedGraph -> VertexHeadNodeList[StartIndex].VertexWeight+UnsignedGraph -> VertexHeadNodeList[OverIndex].VertexWeight);
    193             break;
    194         }
    195         else
    196         {
    197             TmpPointer = TmpPointer -> Next;
    198         }
    199     }
    200 }
    201 
    202 struct UnionFindSet
    203 {
    204     int *ID;
    205     int *Auxiliary;
    206     int GroupSum;
    207     int WeightOriginalTotal;
    208 };
    209 
    210 struct UnionFindSet* UnionFindSetInit(int WeightTotal)
    211 {
    212     struct UnionFindSet *UFSet = malloc(sizeof(struct UnionFindSet));
    213 
    214     UFSet -> GroupSum = WeightTotal;
    215     UFSet -> WeightOriginalTotal = WeightTotal;
    216 
    217     UFSet -> ID = malloc(WeightTotal*sizeof(int));
    218     UFSet -> Auxiliary = malloc(WeightTotal*sizeof(int));
    219 
    220     int i;
    221     for(i = 0; i < WeightTotal; i ++)
    222     {
    223         UFSet -> ID[i] = i;
    224     }
    225     for(i = 0; i < WeightTotal; i ++)
    226     {
    227         UFSet -> Auxiliary[i] = 1;
    228     }
    229 
    230     return UFSet;
    231 }
    232 
    233 int UnionFindSetFind(struct UnionFindSet* UFSet,int WeightNum)
    234 {
    235     if(WeightNum>UFSet -> WeightOriginalTotal-1 || WeightNum<0)
    236     {
    237         return -1;
    238     }
    239 
    240     while(WeightNum != UFSet -> ID[WeightNum])
    241     {
    242         WeightNum = UFSet -> ID[WeightNum];
    243     }
    244     return WeightNum;
    245 }
    246 
    247 int UnionFindSetUnion(struct UnionFindSet* UFSet,int Weight_1,int Weight_2)
    248 {
    249     int WeightRoot_1 = UnionFindSetFind(UFSet,Weight_1);
    250     int WeightRoot_2 = UnionFindSetFind(UFSet,Weight_2);
    251 
    252     if(WeightRoot_1 == -1 || WeightRoot_2 == -1)
    253     {
    254         return -1;
    255     }
    256     if(WeightRoot_1 == WeightRoot_2)
    257     {
    258         return 1;
    259     }
    260 
    261     if(UFSet -> Auxiliary[WeightRoot_1] < UFSet -> Auxiliary[WeightRoot_2])
    262     {
    263         UFSet -> ID[WeightRoot_1] = WeightRoot_2;
    264         UFSet -> Auxiliary[WeightRoot_2] += UFSet -> Auxiliary[WeightRoot_1];
    265     }
    266     else
    267     {
    268         UFSet -> ID[WeightRoot_2] = WeightRoot_1;
    269         UFSet -> Auxiliary[WeightRoot_1] += UFSet -> Auxiliary[WeightRoot_2];
    270     }
    271 
    272     UFSet -> GroupSum --;
    273     return 0;
    274 }
    275 
    276 bool UnionFindSetIsConnected(struct UnionFindSet* UFSet,int Weight_1,int Weight_2)
    277 {
    278     return (UnionFindSetFind(UFSet,Weight_1) == UnionFindSetFind(UFSet,Weight_2));
    279 }
    280 
    281 struct KruskalElem
    282 {
    283     int VertexIndex_1;
    284     int VertexIndex_2;
    285     int ArcWeight;
    286 };
    287 
    288 int CmpStruction(const void *a,const void *b)
    289 {
    290     struct KruskalElem *c = (struct KruskalElem *)a;
    291     struct KruskalElem *d = (struct KruskalElem *)b;
    292 
    293     return  c->ArcWeight > d->ArcWeight ? 1 : 0;
    294 }
    295 
    296 void KruskalMST(struct _Graph *UnsignedGraph)
    297 {
    298     struct UnionFindSet *UFSet = UnionFindSetInit(UnsignedGraph->VertexNum);
    299     struct KruskalElem SortedArcList[2*UnsignedGraph->ArcNum];
    300     int SortedArcListEnd = 0;
    301     
    302     int i;
    303     for(i = 0; i < UnsignedGraph->VertexNum; i ++)
    304     {
    305         struct VertexBodyNode *TmpPointer;
    306         TmpPointer = UnsignedGraph -> VertexHeadNodeList[i].Next;
    307         while(TmpPointer != NULL)
    308         {
    309             SortedArcList[SortedArcListEnd].VertexIndex_1 = i;
    310             SortedArcList[SortedArcListEnd].VertexIndex_2 = TmpPointer -> VertexIndex;
    311             SortedArcList[SortedArcListEnd++].ArcWeight = TmpPointer -> ArcWeight;
    312             TmpPointer = TmpPointer -> Next;
    313         }
    314     }
    315     
    316     qsort(SortedArcList,2*UnsignedGraph->ArcNum,sizeof(struct KruskalElem),CmpStruction);
    317     for(i = 0;i < 2*UnsignedGraph->ArcNum;i ++)
    318     {
    319         if(!UnionFindSetIsConnected(UFSet,SortedArcList[i].VertexIndex_1,SortedArcList[i].VertexIndex_2))
    320         {
    321             printf("%s ¡ª¡ª%s Distance:%d
    ",UnsignedGraph->VertexHeadNodeList[SortedArcList[i].VertexIndex_1].VertexName
    322                                           ,UnsignedGraph->VertexHeadNodeList[SortedArcList[i].VertexIndex_2].VertexName
    323                                           ,SortedArcList[i].ArcWeight);
    324             UnionFindSetUnion(UFSet,SortedArcList[i].VertexIndex_1,SortedArcList[i].VertexIndex_2);
    325         }
    326     }
    327 }
    328 
    329 int main()
    330 {
    331     struct _Graph *G = UGCreat(8,5);
    332     KruskalMST(G);
    333 //    Travel(G);
    334     return 0;
    335 }
    336 
    337 /*
    338         beijing 18
    339         zhengzhou 10
    340         hefei 9
    341         nanjing 12
    342         guangzhou 14
    343         beijing zhengzhou 7
    344         beijing hefei 9
    345         beijing nanjing 8
    346         zhengzhou hefei 5
    347         hefei nanjing 3
    348         zhengzhou guangzhou 7
    349         hefei guangzhou 8
    350         nanjing guangzhou 6
    351 */
  • 相关阅读:
    自编jQuery插件实现模拟alert和confirm
    5.7 Windows常用网络命令
    学历查询和专业代码查询
    学习动态性能表(22)V$resource_limit
    学习动态性能表(21)v$lincense
    学习动态性能表(20)--v$waitstat
    学习动态性能表(19)--v$undostat
    学习动态性能表(18)--v$system_event
    学习动态性能表(17)--v$segstat&v$segment_statistics
    学习动态性能表(16)--v$rowcache
  • 原文地址:https://www.cnblogs.com/Asurudo/p/9427493.html
Copyright © 2020-2023  润新知