数据结构最小生成树两个算法

在无向图中,若任意两个顶点vi与vj都有路径相通,则称该无向图为连通图。(强连通图:在有向图中,若任意两个顶点vi与vj都有路径相通,则称该有向图为强连通图。)
在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接连个顶点的代价,称这种连通图叫做连通网。 一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。
prim算法:
此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。
1.图的所有顶点集合为V;初始令集合u={s},v=V−u;
2.在两个集合u,v能够组成的边中,选择一条代价最小的边(u0,v0),加入到最小生成树中,并把v0并入到集合u中。
3.重复上述步骤,直到最小生成树有n-1条边或者n个顶点为止。
Krustral算法:
此算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。 
1. 把图中的所有边按代价从小到大排序; 
2. 把图中的n个顶点看成独立的n棵树组成的森林; 
3. 按权值从小到大选择边,所选的边连接的两个顶点ui,vi,应属于两颗不同的树,则成为最小生成树的一条边,并将这两颗树合并作为一颗树。 
4. 重复(3),直到所有顶点都在一颗树内或者有n-1条边为止。
//注释的代码本来是想用指针写prim算法,可是比较尴尬没写出来。
 
  
#include
#include
#include
#include
#define MaxInt 1000000
#define MVNum 100
#define Vexcount 4
using namespace std;
typedef unsigned int  ArcType;//边的权值类型
typedef int VerTexType;       //顶点的权值类型
typedef struct
{
    VerTexType vexs[MVNum];   //顶点表
    ArcType arcs[MVNum][MVNum];//邻接矩阵
    int vexnum,arcnum;         //图的当前点数和边数
} AMGraph;
//typedef struct ArcNode         //边结点
//{
//    int adjvex;                //该边所指向的顶点的位置
//    int Valuel;                //该边的权值
//    struct ArcNode*nextarc;    //指向下一条边的指针
//} ArcNode;
//typedef struct VNode
//{
//    VerTexType data;           //顶点信息
//    ArcNode *firstarc;         //指向第一条依附该顶点的边的指针
//} VNOde,AdjList[MVNum];        //AdjList表示邻接表类型
//typedef struct
//{
//    AdjList vertices;          //邻接表
//    int vexnum,arcnum;         //图的当前顶点数和边数
//} ALGraph;
struct node
{
    ArcType adjvex;             //最小边在U中的那个顶点
    ArcType lowcost;            //最小边上的权值
} closedge[MVNum];              //辅助数组,用来记录从顶点集U到V-U的权值最小的边
struct nod
{
    VerTexType Head;              //边的始点
    VerTexType Tail;              //边的终点
    ArcType lowcost;           //边上的权值
} Edge[MVNum];
int Vexset[MVNum];
//int vis[MVNum];
bool cmp(nod Edge1,nod Edge2)
{
    return Edge1.lowcost>G.vexnum>>G.arcnum;     //输入总顶点数,总边数。
    for( i=1; i<=Vexcount; ++i)
        cin>>G.vexs[i];          //依次输入点的信息
    for( j=0; j<=G.vexnum; ++j)   //初始化邻接矩阵,边的权值均置为MaxInt
        for( i=1; i<=G.vexnum; ++i)
            G.arcs[i][j]=MaxInt;
    for( k=0; k>v1>>v2>>w;          //输入一条边依附的顶点及权值
        i=LocateVex(G,v1);
        j=LocateVex(G,v2);
        Edge[k].Head=i;
        Edge[k].Tail=j;
        Edge[k].lowcost=w;
        G.arcs[i][j]=w;          //边的权值置为w
        G.arcs[j][i]=G.arcs[i][j];//置的对称边的权值为w
    }
}//时间复杂度O(n^2)
//void CreatUDG(ALGraph &G)
//{
//    采用邻接表表示法,创建无向网G
//    int i,k,v1,v2,w,j;
//    ArcNode *p1,*p2;
//    cin>>G.vexnum>>G.arcnum;      //输入总顶点数,总边数
//    for( i=1; i<=G.vexnum; ++i)    //输入各点构造表头结点表
//    {
//        cin>>G.vertices[i].data;  //输入顶点值
//        G.vertices[i].firstarc=NULL;//初始化表头结点的指针域为NULL
//    }
//    for( k=1; k<=G.arcnum; ++k)     //输入各边,构造邻接表
//    {
//        cin>>v1>>v2>>w;            //输入一条边依附的两个顶点
//        i=LocateVex(G,v1);
//        j=LocateVex(G,v2);
//        p1=new ArcNode;            //生成一个新的边结点*p1
//        p1->adjvex=j;              //邻接点序号为j
//        p1->Valuel=w;              //边的权值
//        p1->nextarc=G.vertices[i].firstarc;
//        G.vertices[i].firstarc=p1;
//        将新结点*p1插入顶点vi的头部
//        p2=new ArcNode;             //生成另一个对称的新的边结点*p2
//        p2->adjvex=i;               //邻接点序号为i
//        p2->Valuel=w;               //边的权值
//        p2->nextarc=G.vertices[j].firstarc;
//        G.vertices[j].firstarc=p2;
//        将新结点*p2插入顶点vj的头部
//    }
//}//时间复杂度O(n+e)
int Min(struct node *closedge)
{
    unsigned int Min = MaxInt;
    int index = -1;
    for (int i = 1; i <=Vexcount; i++)
    {
        if (closedge[i].lowcost < Min && closedge[i].lowcost !=0)
        {
            Min = closedge[i].lowcost;
            index = i;
        }
    }
    return index;

}
void MiniSpanTree_Prim(AMGraph G,VerTexType u)
{
    int i,j,k,u0,v0,ans=0;
    //无向网G以邻接矩阵形式存储,从顶点u出发构造G的最小生成树T,输出T的各条边
    k=LocateVex(G,u);
    for( j=1; j<=G.vexnum; ++j)
    {
        if(j!=k)
        {
            closedge[j].adjvex=k;
            closedge[j].lowcost=G.arcs[k][j];
        }
    }
    closedge[k].lowcost=0;                     //初始
    closedge[k].adjvex=k;
    for( i=2; i<=G.vexnum; ++i)                  //选择其余n-1个顶点,生成n-1条边
    {
        k=Min(closedge);
        //求出T的下一个结点:第k个顶点,closedge[k]中存有当前最小边
        u0=closedge[k].adjvex;
        v0=G.vexs[k];
        ans+=closedge[k].lowcost;
        cout<

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