Krusal算法 方法2

// krusal   算法根据   MST   性质。若点集合 U ~ 点集合   V   存在一点最短路径 s~t,   则最小生成树必包含   s~t   这条路。
//   利用反证法(或者剪贴法)可以证明

// krusal   算法是将整个图每个顶点看成一个集合。主要是合并集合,直到只剩一个集合为止

//   同时考虑以边为对象的   有向图



// 用最小边去找集合
#include   "stdafx.h"
#include  
#include  
#include  
#include  

enum
{
        Vertex_No_Connection       = -1,
        Vertex_Total_Number      = 5,
        Vertex_Max_Edge_Value      = 10000,
};


int   arrayPathScheme   [   Vertex_Total_Number ][   Vertex_Total_Number   ] =
{
     0,   10,   -1,  30,  100,
     -1,   0,   50,  -1,   -1,
     -1,  -1,   0,   -1,   10,
     -1,  -1,   20,   0,   60,
     -1,  -1,   -1,  -1,    0,
};

//   集合
struct   SVertexSet
{
        int   idSet   ;
        std :: list   < int >   listVertex ;
};

std   :: list <   SVertexSet *>   listVertexSet   ;

//   三元表
struct   SEdgeInfoNode
{
        int   nEdgeValue   ;
        int   nSourceVertex   ;
        int   nEndVertex   ;
};

//   三元表   并且递增
std   :: list <   SEdgeInfoNode *>   listEdgeInfoSet   ;

bool   SortByCmp (   SEdgeInfoNode * & pPre   ,   SEdgeInfoNode * & pNext   )
{
        if (   pPre   -> nEdgeValue   <   pNext -> nEdgeValue   )
             return   true   ;

        return   false   ;
}

void   PrintAll ()
{
        std :: list   < SEdgeInfoNode *>::   iterator   iBegin   =   listEdgeInfoSet   . begin ();
        std :: list   < SEdgeInfoNode *>::   iterator   iEnd      =   listEdgeInfoSet   . end ();
        for ( ;   iBegin   !=   iEnd ; ++   iBegin   )
     {
             SEdgeInfoNode *   pEdgeInfo   = (* iBegin );
             if (   pEdgeInfo   )
          {
                 std :: cout   << " Source->" <<   pEdgeInfo -> nSourceVertex   << " Dest->" <<   pEdgeInfo -> nEndVertex   << "   Vlaue:" <<   pEdgeInfo -> nEdgeValue   << std ::   endl ;
          }
     }
}

void   arrayInit ()
{
        //   数组预处理处理回环的值   i -> j = 50    同时   j -> i = 30.
        //   注销回环。则将 i -> j = 50   改为 i -> j = -1.
        for (   int   i   = 0;   i   <   Vertex_Total_Number   - 1; ++ i   )
     {
             for (   int   j   =   i   + 1;   j   <   Vertex_Total_Number ; ++   j   )
          {
                 if (   arrayPathScheme   [ i ][   j ] > 0 &&   arrayPathScheme   [ j ][   i ] > 0 )
              {
                      if (   arrayPathScheme   [ i ][   j ] <   arrayPathScheme   [ j ][   i ] )
                           arrayPathScheme [ j   ][ i ] = -1;
                      else
                           arrayPathScheme [ i   ][ j ] = -1;
              }
          }
     }

        //   初始化顶点集合
        listVertexSet . clear   ();
        for (   int   i   = 0;   i   <   Vertex_Total_Number   ; ++ i   )
     {
             SVertexSet *   pVertexNode   =   new   SVertexSet ;
             if ( ! pVertexNode   )
          {
                 std :: cout   << "Error 2" <<   std :: endl   ;
                 system ( "pause"   );
                 return   ;
          }

             pVertexNode -> idSet   =   i ;
             pVertexNode -> listVertex   . push_back (   i   );
          
             listVertexSet . push_back   (   pVertexNode   );
     }

        //   初始化三元表
        listEdgeInfoSet . clear   ();
        for (   int   i   = 0;   i   <   Vertex_Total_Number   ; ++ i   )
     {
             for (   int   j   = 0;   j   <   Vertex_Total_Number   ; ++ j   )
          {
                 int   nEdgeValue   =   arrayPathScheme [   i ][ j   ];
                 if ( 0 ==   nEdgeValue   || -1 ==   nEdgeValue   )
                      continue ;

                 SEdgeInfoNode *   pEdgeInfoNode   =   new   SEdgeInfoNode   ;
                 if ( ! pEdgeInfoNode   )
              {
                      std :: cout   << "Error 3" <<   std :: endl   ;
                      system ( "pause"   );
                      return   ;
              }

                 pEdgeInfoNode -> nEdgeValue        =   nEdgeValue ;
                 pEdgeInfoNode -> nSourceVertex     =   i ;
                 pEdgeInfoNode -> nEndVertex        =   j ;

                 listEdgeInfoSet . push_back   (   pEdgeInfoNode   );
          }
     }

        //PrintAll();
        listEdgeInfoSet . sort   (   SortByCmp   );
        //std::cout<
        //PrintAll();
}

bool   IsInTheSameSet (   int   nSourceIndex   ,   int   nDestIndex ,   SVertexSet   * & pSourceSet ,   SVertexSet * & pDestSet   );

int   _tmain (   int   argc   ,   _TCHAR *   argv [])
{
        arrayInit ();

        int   nSelectedEdge   = 0;     //   当边取出为   Vertex_Total_Num - 1   条时,则最小生成树构建完成
        std :: list   < SEdgeInfoNode *>::   iterator   listEdgeBegin   =   listEdgeInfoSet   . begin ();
        std :: list   < SEdgeInfoNode *>::   iterator   listEdgeEnd      =   listEdgeInfoSet   . end ();
        for ( ;   listEdgeBegin   !=   listEdgeEnd ; ++   listEdgeBegin   )
     {
             SEdgeInfoNode *   pEdgeInfoNode   = (* listEdgeBegin );
             if ( ! pEdgeInfoNode   )
          {
                 std :: cout   << "Error 4" <<   std :: endl   ;
                 system ( "pause"   );
                 return   0;
          }

             int     nSourceIndex   =   pEdgeInfoNode   -> nSourceVertex ;
             int     nDestIndex      =   pEdgeInfoNode ->   nEndVertex ;
             SVertexSet *   pSourceSet   =   NULL ;
             SVertexSet *   pDestSet      =   NULL ;
          
             bool   bIsInTwoSet   =   IsInTheSameSet (   nSourceIndex ,   nDestIndex   ,   pSourceSet ,   pDestSet   );
             if (   true   ==   bIsInTwoSet   )
          {
                 //   在同一集合内   则不处理,取下一条边
                 continue ;
          }
             else   
          {
                 //   在不同的集合内
                 //   pSourceSet   合并到   pDest   集合中
                 if ( ! pSourceSet   ||  ! pDestSet   )
              {
                      std :: cout   << "Error 5" <<   std :: endl   ;
                      system ( "pause"   );
                      return   0;
              }

                 std :: copy   (   pSourceSet ->   listVertex . begin   (),   pSourceSet   -> listVertex .   end (),   pDestSet   -> listVertex .   begin () );
                 std :: list   < SVertexSet *>::   iterator   ilistFind   =   listVertexSet   . begin ();
                 std :: list   < SVertexSet *>::   iterator   ilistEnd     =   listVertexSet   . end ();
                 for ( ;   ilistFind   !=   ilistEnd ; ++   ilistFind   )
              {
                      if ( (* ilistFind   ) && (* ilistFind ) ==   pDestSet   )
                           break ;
              }
                 if (   ilistFind   !=   listVertexSet .   end () )
                      listVertexSet . erase   (   ilistFind   );

                 delete   pDestSet   ;

              ++   nSelectedEdge ;
                 //   输出
                 std :: cout   << " SourceNode-> " <<   pEdgeInfoNode -> nSourceVertex   << "  DestNode->" <<   pEdgeInfoNode -> nEndVertex   << "  NodeValue:" <<   pEdgeInfoNode -> nEdgeValue   << std ::   endl ;

                 if (   Vertex_Total_Number   - 1 ==   nSelectedEdge   )
                      break ;
          }
     }

        system (   "pause"   );
        return   0;
}

bool   IsInTheSameSet (   int   nSourceIndex   ,   int   nDestIndex ,   SVertexSet   * & pSourceSet ,   SVertexSet * & pDestSet   )
{
        int   idSetSource   = -1,   idSetDest   = -1;
        std :: list   < SVertexSet *>::   iterator   ilistVertexBegin   =   listVertexSet   . begin ();
        std :: list   < SVertexSet *>::   iterator   ilistVertexEnd      =   listVertexSet   . end ();
        for ( ;   ilistVertexBegin   !=   ilistVertexEnd ; ++ ilistVertexBegin   )
     {
             SVertexSet *   pNowVertex   = (* ilistVertexBegin );
             if ( ! pNowVertex   )
          {
                 std :: cout   << "Error 6" <<   std :: endl   ;
                 system ( "pause"   );
                 return   0;
          }

             std :: list   < int >::   iterator   ilistIntBegin     pNowVertex   -> listVertex .   begin ();
             std :: list   < int >::   iterator   ilistIntEnd      =    pNowVertex   -> listVertex .   end ();
             for ( ;   ilistIntBegin   !=   ilistIntEnd ; ++ ilistIntBegin   )
          {
                 if ( (* ilistIntBegin   ) ==   nSourceIndex   )
              {    
                      idSetSource     pNowVertex   -> idSet ;
                      pSourceSet   =    pNowVertex   ;
              }

                 if ( (* ilistIntBegin   ) ==   nDestIndex   )
              {
                      idSetDest   =    pNowVertex   -> idSet ;
                      pDestSet    =    pNowVertex ;
              }
          }


             if (   idSetDest   != -1 &&   idSetSource   != -1 )
                 break ;
     }

        if (   idSetSource   != -1 &&   idSetSource   ==   idSetDest   )
             return   true   ;

        return   false   ;
}



  

你可能感兴趣的:(数据结构)