数据结构之图2

十字链表:整合了邻接表和逆邻接表,即容易找到v1的头,也能找到v1的尾,因而容易求得顶点的出度和入度。

边集数组:由两个一维数组构成,一个存储顶点信息,一个存储边的信息。这个边数组每个数据元素由一条边的起点下标,终点下标和权组成。

图的遍历:从图中一个顶点开始访遍图中其余的顶点,且使每个顶点仅访问一次,这一过程叫做图的遍历。

typedef int Boolean;        
Boolean visited[MAX];

//邻接矩阵的深度优先递归算法
void DFS(MGraph G,int i)
{
    int j;
    visited[i] = TRUE;
    printf("%c",G.vexs[i]);
    for(j = 0;j < G.numVertexes;j++)
    {
        if(G.arc[i][j] == 1 &&!visited[j])
            DFS(G,j);
    }
}

//邻接矩阵的深度遍历操作
void DFSTraverse(MGraph G)
{
    int i;
    for(i = 0;i < G.numVertexes;i++)
        visited[i] = FALSE;         //初始所以顶点状态都是未访问过状态
    for(i = 0;i <G.numVertexes;i++)
        if(!visited[i])         //对未访问过的顶点调用DFS,若是连通图,只会执行一次
            DFS(G,i);
}
//邻接表的深度优先递归遍历算法
void DFS(GraphAdjList GL,int i)
{
    EdgeNode *p;
    visited[i] = TRUE;
    printf("%c",GL->adjList[i].data);
    p = GL->adjList.firstedge;
    while(p)
    {
        if(!visited[p->adjvex])
            DFS(GL,p->adjvex);
        p = p->next;
    }
}


//邻接表的深度遍历操作
void DFSTraverse(GraphAdjList GL)
{
    int i;
    for(i = 0;i < GL->numVertexes;i++)
        visited = FALSE;
    for(i = 0;i < GL->numVertexes;i++)
        if(!visited[i])
            DFS(GL,i);
}
//邻接矩阵的广度遍历算法
void BFSTraverse(MGraph G)
{
    int i,j;
    Queue Q;
    for(i = 0;i < G.numVertexes;i++)
        visited[i] = FALSE;
    InitQueue(&Q);      //初始化辅助队列
    for(i = 0;i < G.numVertexes;i++)
    {
        if(!visited[i])
        {
            visited[i] = TRUE;
            printf("%c",G.vexs[i]);
            EnQueue(&Q,i);      //将顶点入队列
            while(!QueueEmpty(Q))
            {
                DeQueue(&Q,&i);     //将队中元素出队列,赋值给i
                for(j = 0;j < G.numVertexes;j++)
                {
                    //判断其他顶点若与当前顶点存在边且未访问过
                    if(G.arc[i][j] == 1 && !visited[j])
                    {
                        visited[j] = TRUE;
                        printf("%c",G.vex[j]);
                        EnQueue(&Q,j);
                    }
                }
            }

        }
    }
}
//邻接表广度遍历算法
void BFSTraverse(GraphAdjList GL)
{
    int i;
    EdgeNode *p;
    Queue Q;
    for(i = 0;i < GL->numVertexes;i++)
        visited[i] = FALSE;
    InitQueue(&Q);
    for(i = 0;i < GL->numVertexes;i++)
    {
        if(!visited[i])
        {
            visited[i] = TRUE;
            printf("%c",GL->adjList[i].data);
            EnQueue(&Q,i);
            while(!QueueEmpty(Q))
            {
                DeQueue(&Q,&i);
                p = GL->adjList[i].firstedge;   //找到当前顶点边表链表头指针
                while(p)
                {
                    if(!visited[p->adjvex])
                    {
                        visited[p->adjvex] == TRUE;
                        printf("%c",GL->adjList[p->adjvex].data);
                        EnQueue(&Q,p->adjvex);  //将此顶点入队列
                    }
                    p = p->next;        //指向下一个邻接点
                }
            }
        }
    }
}

构造连通网的最小代价生成树称为最小生成树。

//prim算法最小生成树
void MiniSpanTree_Prim(MGraph G)
{
    int min,i,j,k;
    int adjvex[MAXVEX]; //保存相关顶点下标
    int lowcost[MAXVEX];//保存相关顶点间边的权值
    lowcost[0] = 0; //初始化第一个权值为0,即v0加入生成树
    adjvex[0] = 0;  //初始化第一个顶点下标为0
    for(i = 1;i < G.numVertexes;i++)    //循环除下标为0外的全部顶点
    {
        lowcost[i] = G.arc[0][i];//将v0顶点与之有边的权值存入数组
        adjvex[i]= 0;       //初始化都为v0的下标
    }
    for(i = 1;;i <G.numVertexes;i++)
    {
        min = INFINITY; //初始化最小权值为无穷
        j = 1;k = 0;
        while(j < G.numVertexes)
        {
            if(lowcost[j]!= 0 && lowcost[j] < min)
            {
                //如果权值不为0,且权值小于min
                min = lowcost[j];   //当前权值为最小值
                k = j;
            }
            j++;
        }
        printf("(%d,%d)",adjvex[k],k);
        lowcost[k] = 0;
        for(j = 1;j < G.numVertexes;j++)
        {
            if(lowcost[j]!= 0&&G.arc[k][j] < lowcost[j])
            {
                lowcost[j] = G.arc[k][j];
                adjvex[j] = k;
            }
        }
    }
}
//Kruskal算法生成最小生成树
void MiniSpanTree_Kruskal(MGraph G)
{
    int i,n,m;
    Edge edges[MAXEDGE];    //定义边集数组
    int parent[MAXVEX];     //定义数组用来判断边与边是否形成环路
    for(i = 0;i <G.numVertexes;i++)
        parent[i] = 0;
    for(i = 0;i <G.numEdges;i++)
    {
        n = Find(parent,edges[i].begin);
        m = Find(parent,edges[i].end);
        if(n != m)      //假如n与m不等,说明此边没有与现有生成树形成环路
        {
            parent[n] = m;
            printf("(%d,%d)%d",edged[i].begin,edges[i].end,edges[i].weight);
        }
    }
}

int Find(int *parent,int f)//查找连线顶点的尾部下标
{
    while(parent[f]>0)
        f = parent[f];
    return f;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值