图的邻接表

#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100      //最大顶点数
typedef char VertexType;     //顶点
typedef int EdgeType;   //权值
#define UNVISITED -1    //标记未访问
#define VISITED 1   //标记未访问

typedef struct
{
    int from;   //边的始点
    int to; //边的终点
    EdgeType weight;    //权重
}Edge;  //边的结构


typedef struct EdgeNode
{
    int adjvex; //该顶点对应的下标
    EdgeType weight;    //权重
    struct EdgeNode * next;
}EdgeNode;

typedef struct  //顶点结构
{
    VertexType data;
    EdgeNode * firstedge;
}VertexNode,AdjList[MAXVEX];

typedef struct
{
    AdjList adjList;
    int numVertexes;
    int numEdges;
    int Indegree[MAXVEX];
    int Mark[MAXVEX];   //标记是否被访问过
}GraphAdjList;  //图结构


//初始化邻接表
void InitGraphAdjList(GraphAdjList * G,int numVer,int numEd)    //传入顶点数和边数
{
    G->numVertexes=numVer;
    G->numEdges=numEd;
    for(int i=0;i<G->numVertexes;i++)
    {
        G->Mark[i]=UNVISITED;
        G->Indegree[i]=0;
        G->adjList[i].firstedge=NULL;   //将边表置空表
    }
}


//创建一条边(无向图)
void UCreat_Edge(GraphAdjList * G,int from,int to,int weight)
{
    EdgeNode * temp1 = G->adjList[from].firstedge;
    EdgeNode * temp2 = G->adjList[to].firstedge;
    if(temp1==NULL)
    {
        EdgeNode * NewEdgeNode1=(EdgeNode *)malloc(sizeof(EdgeNode));
        NewEdgeNode1->adjvex=to;
        NewEdgeNode1->weight=weight;
        NewEdgeNode1->next=NULL;
        G->adjList[from].firstedge=NewEdgeNode1;
        G->Indegree[from]++;
    }
    else
    {
        while(temp1->next!=NULL)
        {
            temp1=temp1->next;
        }
        EdgeNode * NewEdgeNode1=(EdgeNode *)malloc(sizeof(EdgeNode));
        NewEdgeNode1->adjvex=to;
        NewEdgeNode1->weight=weight;
        NewEdgeNode1->next=NULL;
        temp1->next=NewEdgeNode1;
        G->Indegree[from]++;

    }
    if(temp2==NULL)
    {
        EdgeNode * NewEdgeNode2=(EdgeNode *)malloc(sizeof(EdgeNode));
        NewEdgeNode2->adjvex=from;
        NewEdgeNode2->weight=weight;
        NewEdgeNode2->next=NULL;
        G->adjList[to].firstedge=NewEdgeNode2;
        G->Indegree[to]++;
    }
    else
    {
        while(temp2->next!=NULL)
        {
            temp2=temp2->next;
        }
        EdgeNode * NewEdgeNode2=(EdgeNode *)malloc(sizeof(EdgeNode));
        NewEdgeNode2->adjvex=from;
        NewEdgeNode2->weight=weight;
        NewEdgeNode2->next=NULL;
        temp2->next=NewEdgeNode2;
        G->Indegree[to]++;
    }
}


//创建一条边(有向图)
void Creat_Edge(GraphAdjList * G,int from,int to,int weight)
{
    EdgeNode * temp= G->adjList[from].firstedge;
    if(temp==NULL)
    {
        EdgeNode * NewEdgeNode=(EdgeNode *)malloc(sizeof(EdgeNode));
        NewEdgeNode->adjvex=to;
        NewEdgeNode->weight=weight;
        NewEdgeNode->next=NULL;
        G->adjList[from].firstedge=NewEdgeNode;
        G->Indegree[to]++;
    }
    else
    {
        while(temp->next!=NULL)
        {
            temp=temp->next;
        }
        EdgeNode * NewEdgeNode=(EdgeNode *)malloc(sizeof(EdgeNode));
        NewEdgeNode->adjvex=to;
        NewEdgeNode->weight=weight;
        NewEdgeNode->next=NULL;
        temp->next=NewEdgeNode;
        G->Indegree[to]++;

    }
}


/*建立图的邻接表结构(无向图)*/
void UGreateALGraph(GraphAdjList * G)
{
    int i,j,k,w;
    EdgeNode * e;
    EdgeNode * a;
    printf("请输入%d个元素:\n",G->numVertexes);
    for(i=0;i<G->numVertexes;i++)   /*读入顶点信息,建立顶点表*/
    {
        scanf(" %c",&G->adjList[i].data);   /*输入顶点信息*/
        G->adjList[i].firstedge=NULL;   /*将边表置空表*/
    }
    for(k=0;k<G->numEdges;k++)  /*建立边表*/
    {
        printf("输入边(Vi,Vj)上的顶点序号和权重:\n");
        scanf("%d%d%d",&i,&j,&w);   /*输入(Vi,Vj)上的顶点序号*/
        UCreat_Edge(G,i,j,w);
    }
}



/*建立图的邻接表结构(无向图)*/
void GreateALGraph(GraphAdjList * G)
{
    int i,j,k,w;
    EdgeNode * e;
    EdgeNode * a;
    printf("请输入%d个元素:\n",G->numVertexes);
    for(i=0;i<G->numVertexes;i++)   /*读入顶点信息,建立顶点表*/
    {
        scanf(" %c",&G->adjList[i].data);   /*输入顶点信息*/
        G->adjList[i].firstedge=NULL;   /*将边表置空表*/
    }
    for(k=0;k<G->numEdges;k++)  /*建立边表*/
    {
        printf("输入边(Vi,Vj)上的顶点序号和权重:\n");
        scanf("%d%d%d",&i,&j,&w);   /*输入(Vi,Vj)上的顶点序号*/
        Creat_Edge(G,i,j,w);
    }
}

Edge FirstEdge(GraphAdjList * G,int oneVertex)
{
    Edge firstEdge;
    firstEdge.from=oneVertex;
    EdgeNode * temp=G->adjList[oneVertex].firstedge;
    if(temp!=NULL)
    {
        firstEdge.to=temp->adjvex;
        firstEdge.weight=temp->weight;
    }
    else
    {
        firstEdge.to=-1;
        firstEdge.weight=-1;
    }
    return firstEdge;
}




//返回oneEdge的终点
int ToVertex(Edge oneEdge)
{
    return oneEdge.to;
}




//返回与perEdge相同顶点的下一条边
Edge NextEdge(GraphAdjList * G,Edge perEdge)
{
    Edge myEdge;
    myEdge.from=perEdge.from;
    EdgeNode * temp=G->adjList[perEdge.from].firstedge;
    while(temp!=NULL && temp->adjvex<=perEdge.to)
    {
        temp=temp->next;
    }
    if(temp!=NULL)
    {
        myEdge.to=temp->adjvex;
        myEdge.weight=temp->weight;
    }
    else
    {
        myEdge.to=-1;
        myEdge.weight=-1;
    }
    return myEdge;
}


//判断是否为边
bool IsEdge(Edge oneEdge)
{
    if(oneEdge.to==-1)
    {
        return false;
    }
    else
    {
        return true;
    }
}





//访问当前的顶点
void Vist(GraphAdjList * G,int v)
{
    printf("%c ",G->adjList[v]);
}


//图的深度优先周游(DFS)算法
void DFS(GraphAdjList * G,int v)
{
    G->Mark[v]=VISITED;
    Vist(G,v);
    for(Edge e=FirstEdge(G,v);IsEdge(e);e=NextEdge(G,e))
    {
        if(G->Mark[ToVertex(e)]==UNVISITED)
        {
            DFS(G,ToVertex(e));
        }
    }
}



int main()
{

    GraphAdjList G;
    int numVer,numEd;
    int start;
    int choose;
    printf("请输入顶点元素个数和边数:\n");
    scanf("%d%d",&numVer,&numEd);
    InitGraphAdjList(&G,numVer,numEd);
    printf("请选择:\n1.无向图\n2.有向图\n");
    scanf("%d",&choose);
    if(choose==1)
    {
        UGreateALGraph(&G);
    }
    else if(choose==2)
    {
        GreateALGraph(&G);
    }
    else
    {
        printf("选择错误!\n");
        return 0;
    }
    printf("请选择以哪个顶点作为起始点遍历,请输入其下标:\n");
    scanf("%d",&start);
    DFS(&G,start);
    printf("\n");
    return 0;
}

这里写图片描述 这里写图片描述
这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值