图----数据结构图论总结(四)

文章都是摘录的网络中比较好的代码,因为图的四种存储方式中有两种方式(邻接矩阵和连接表)普通书上都有以此建立图的代码,所以在此不在累赘列出

*******************************************************************************

建立无向图的邻接多重表

题目:编写一个算法由依次输入的顶点数目,边的数目,各顶点的信息和各条边的信息建立无向图的邻接多重表。

一.   需求分析

  这里需要两个主要字函数,一个是建立图,另一个是打印图。

二.   概要设计

首先是建立两个结点,一个是边结点,另一个是顶点结点,分别为struct Edge,struct Node,然后建立图,Create_ML_Graph(int Vertex1,NextEdge New),紧接着是打印Print_ML_Graph(struct Node *Head)。

三.   详细设计

  

#include <stdlib.h>

#include <stdio.h>

#define VertexNum  6

struct Edge

{int Marked;

 int Vertex1;

 int Vertex2;

 struct Edge *Edge1;

 struct Edge *Edge2;

};

 typedef struct Edge *NextEdge;

 struct Node

{int Vertex;

 struct Edge *Next;

};

 typedef struct Node *Graph;

 struct Node Head[VertexNum];

 void Create_ML_Graph(int Vertex1,NextEdge New)

{NextEdge Pointer;

 NextEdge Previous;

 Previous=NULL;

 Pointer=Head[Vertex1].Next;

 while(Pointer!=NULL)

{Previous=Pointer;

 if (Pointer->Vertex1==Vertex1)

 Pointer=Pointer->Edge1;

 else  Pointer=Pointer->Edge2;

 }

 if(Previous==NULL)

 Head[Vertex1].Next=New;

 else if(Previous->Vertex1==Vertex1)

 Previous->Edge1=New;

 else Previous->Edge2=New;

 }

 void Print_ML_Graph(struct Node *Head)

{NextEdge Pointer;

 Pointer=Head->Next;

 while(    Pointer!=NULL)

{printf("(%d,%d)",Pointer->Vertex1,Pointer->Vertex2);

 if(Head->Vertex==Pointer->Vertex1)

 Pointer=Pointer->Edge1;

 else if(Head->Vertex==Pointer->Vertex2)

 Pointer=Pointer->Edge2;

 }

 printf("/n");

}

void main()

{int Source;

 int Destinition;

 NextEdge New;

 int i;

 for(i=0;i<VertexNum;i++)

 {Head[i].Vertex=i;

  Head[i].Next=NULL;}

  while(1)

 {printf("Please input the Edge's source:");

 scanf("%d",&Source);

 if(Source==-1) break;

 printf("Please input the Edge's Destinition:");

 scanf("%d",&Destinition);

 if(Source>=VertexNum||Destinition>=VertexNum)

 printf("@Error@:out of range!!/n");

 else

 { New=(NextEdge) malloc(sizeof(struct Edge));

  if(New!=NULL)

 {New->Vertex1=Source;

  New->Vertex2=Destinition;

  New->Edge1=NULL;

  New->Edge2=NULL;

  Create_ML_Graph(Source,New);}

  }

 }

 printf("##Graph##/n");

 for(i=0;i<VertexNum;i++)

 {printf("Vertex[%d]:",i);

  Print_ML_Graph(&Head[i]);

  }

 }

四.   调试分析

  这个题在调试时,除了常规的变量的定义和指针等错误外,主要是指针的值传不过去,导致打印的时候输入的图打印不出来,检查的时候看各指针是不是传过去了(用单步执行)。

五.   用户使用说明

  运行程序时,首先是让你选择这时你输入1回车,这时让你输入头结点数,你可以输入1或2等(但不能大于6,这里设的最大值是6),紧接着让你输入尾结点,你照样输入(不能大于6),这样反复输入几次也就是几条边后回车,就可以看结果。

六.   测试结果

  依次输入1,2,1,3,2,4,回车

可以看到 <1,2><1,3><2,4>

 

 

 

*************************************************************

有向图的十字链表存储结构

/**
说明:有向图的十字链表存储结构,同时编写了以下函数
        1:建立十字链表的函数
        2:输出有向图包括顶点和弧
        3:计算顶点的入度和出度
        4:深度优先遍历有向图
*/
#include <stdio.h>
#include <malloc.h>
#define OK 1
#define MAX 100

typedef char ElemType ;

typedef struct arcNode{                 //定义有向图的弧结点
    int tailvex, headvex;                    //弧尾和弧头在图中的位置
    struct arcNode *hlink,*tlink;
}ArcNode;

typedef struct vexNode{                    //定义顶点结点
    ElemType data;
    ArcNode *firstin,*firstout;
}VexNode;

typedef struct olgraph{                    //定义有向图的十字链表
    VexNode xlist[MAX];
    int vexnum,arcnum;
}OLGraph;

ArcNode *ptr[MAX];                                        //定义访问图的辅助向量
int visited[MAX];                                            //定义顶点访问标志

int locateVex(OLGraph *g, ElemType a)
{    int s;
    for(s=0;s<g->vexnum;s++)
        if(g->xlist[s].data==a)        return s;
    return -1;                                        //未找到则返回-1
}

void create(OLGraph *G)
{    int i,j,k;
    ElemType v1,v2,v,vv;
    ArcNode *p;
    printf("/n/n/n/n*********** begin of creating *******************");
    printf("/ninput number of vnum,arcnum:");
    scanf("%d,%d",&G->vexnum,&G->arcnum);
    printf("/ninput data of vex:/n");
    for(i=0;i<G->vexnum;i++)
    {    scanf("%*c%c",&v);                //输入图中顶点
        G->xlist.data=v;
        G->xlist.firstin=NULL;        //初始化以顶点为弧头和弧尾的链表
        G->xlist.firstout=NULL;
    }
    printf("/n/ninput data of edge(v1v2)/n");
    for(k=0;k<G->arcnum;k++)            //输入图中的弧
    { scanf("%*c%c%c",&v1,&v2);
        i=locateVex(G,v1);
        j=locateVex(G,v2);
        p=(ArcNode *)malloc(sizeof(ArcNode));
        p->tailvex=i;p->headvex=j;

        p->hlink=G->xlist[j].firstin;
        p->tlink=G->xlist.firstout;
        G->xlist[j].firstin=G->xlist.firstout=p;
    }
    printf("*********** end of creating *******************");
    //return G;
}

void printGraph(OLGraph *g)
{    ArcNode *p;
    int i;
    printf("/n/nthe edges are:");
    for(i=0; i<g->vexnum; i++)            //输出图中的弧
    { p=g->xlist.firstout; printf("/n  %c:",g->xlist.data);
        while(p!=NULL)
        { printf("    %c----->%c",g->xlist.data, g->xlist[p->headvex].data);
            p=p->tlink;
        }
    }
}

int outNumNode(ArcNode *p)                //计算弧尾相同链表的结点数
{    int n=0;
    while (p!=NULL) { n++; p=p->tlink; }
    return n;
}

int inNumNode(ArcNode *p)                    //计算弧头相同链表的结点数
{    int n=0;
    while (p!=NULL) { n++; p=p->hlink; }
    return n;
}

int outDegree(OLGraph *g, ElemType a)//计算某结点的出度
{    int i, outNumber=0;
    outNumber=outNumNode(g->xlist[locateVex(g,a)].firstout);
    return outNumber;
}

int inDegree(OLGraph *g, ElemType a)//计算某结点的入度
{    int i, inNumber=0;
    inNumber=inNumNode(g->xlist[locateVex(g,a)].firstin);
    return inNumber;
}

void printDegree(OLGraph *g)                //输出结点的度数
{    int i;
    printf("/n/nthe outDegree of vexs are:");
    for(i=0; i<g->vexnum; i++)
    {    printf("/n  %c: %d",g->xlist.data, outDegree(g,g->xlist.data));    }

    printf("/n/nthe inDegree of vexs are:");
    for(i=0; i<g->vexnum; i++)
    {    printf("/n  %c: %d",g->xlist.data, inDegree(g,g->xlist.data));    }
}

void dfs(OLGraph *g, int indexV)                //以某顶点出发深度优先遍历图
{ int w;
    printf("%4c", g->xlist[indexV].data);
    visited[indexV]=1;                             // 访问此结点,并设置标志
    while (ptr[indexV]!=NULL)
    {    w= ptr[indexV]->headvex;          //取结点的邻接顶点w
        if( visited[w]==0 ) dfs(g, w);
        ptr[indexV]=ptr[indexV]->tlink;                      // 记住顶点v 的邻接顶点位置,
    }                                        //  该邻接点在w之后
}

void depthFirst(OLGraph *g)                            //深度优先遍历图
{ int i;
    for (i=0; i<g->vexnum; i++)
    {    ptr=g->xlist.firstout;                //每个顶点链表的第一个结点的地址
        visited=0;                          //给每个结点一个未访问标记
    }
    printf("/n/nthe traverse of depthFirst are:");
    for(i=0; i<g->vexnum; i++)                                    //调用以顶点vi为出发点的深度优先遍历图G的算法
        if (visited == 0) dfs(g,i);
    printf("/nthe end of traverse");
}

 

void main()
{ OLGraph g;
    create(&g);
    printGraph(&g);
    printDegree(&g);
    depthFirst(&g);
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值