查找算法

      图

单源点最短路径的Dijkstra算法

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 6

#define INF 32767

void Ppath(int path[],inti,int v0)

{//先序递归查找最短路径上的顶点

    int k;

    k=path[i];

    if(k!=v0)//顶点vk不是源点v0时

    {

        Ppath(path,k,v0);//递归查找顶点vk的前一个顶点

        printf("%d,",k);//输出顶点vk

    }

}

void Dispath(int dist[],intpath[],int s[],int v0,int n)

{//输出最短路径函数

    int i;

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

    if(s[i]==1)

    {

        printf("从%d到%d的最短路径长度为:%d,路径为:",v0,i,dist[i]);

        printf("%d,",v0);//输出路径上的源点v0

        Ppath(path,i,v0);//输出路径上的中间顶点vi

        printf("%d\n",i);//输出路径上的终点

    }

    else

       printf("从%d到%d不存在最短路径\n",v0,i);

}

void Dijkstra(intgm[][MAXSIZE],int v0,int n)

{

    int dist[MAXSIZE],path[MAXSIZE],s[MAXSIZE];

    int i,j,k,mindis;

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

    {

        dist[i]=gm[v0][i];

        s[i]=0;//s[i]=0表示顶点vi属于T集

        if(gm[v0][i]<INF)//路径初始化

        path[i]=v0;//源点v0是vi当前最短路径中的前一个顶点

        else

          path[i]=-1;//v0到v1没有边

    }

    s[v0]=1;path[v0]=0;//v0并入集合S且v0的当前最短路径中午前一个顶点

    for(i=0;i<n;i++)//对除v0外的n-1顶点寻找最短路径

    {

        mindis=INF;

        for(j=0;j<n;j++)//从当前集合T中选择一个路经长度最短的顶点vk

         if(s[j]==0&&dist[j]<mindis)

           {

               k=j;

               mindis=dist[j];

           }

           s[k]=1;//顶点vk加入集合s中

           for(j=0;j<n;j++)//调整源点v0到集合T中任一顶点vj的路径长度

           if(s[j]==0)//顶点vj在集合T中

          if(gm[k][j]<INF&&dist[k]+gm[k][j]<dist[j])

              {//当v0到vj的路径长度小于v0到vk和vk到vj的路径长度是

                  dist[j]=dist[k]+gm[k][j];

                  path[j]=k;//vk是当前最短路径中vj的前一个顶点

              }

    }

    Dispath(dist,path,s,v0,n);//输出最短路径

}

void main()

{

    intg[MAXSIZE][MAXSIZE]={{INF,20,15,INF,INF,INF},{2,INF,INF,INF,10,30},{INF,4,INF,INF,INF,10},{INF,INF,INF,INF,INF,INF},{INF,INF,INF,15,INF,INF},{INF,INF,INF,4,10,INF}};

    Dijkstra(g,0,6);//求顶点0的最短路径

}

                             关键路径

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node//邻接表结点

{

    int adjvex;//邻接点域

    int info;

    struct node *next;//指向下一个邻接边结点的指针域

}EdgeNode;//邻接表结点类型

typedef struct vnode//顶点表结点

{

    int indegree;//顶点入度

    int vertex;//顶点域

    EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域

}VertexNode;//顶点表结点类型

typedef struct

{

    char data[MAXSIZE];

    int top;

}SeqStack;

void Init_SeqStack(SeqStack**s)

{//初始化

    *s=(SeqStack *)malloc(sizeof(SeqStack));

    (*s)->top=-1;

}

int Empty_SeqStack(SeqStack*s)

{

    if(s->top==-1)

    return 1;

    else

     return 0;

}

void Push_SeqStack(SeqStack*s,int x)

{//入栈

    if(s->top==MAXSIZE-1)

    printf("Stack is full!\n");

    else

     {

         s->top++;

         s->data[s->top]=x;

     }

}

void Pop_SeqStack(SeqStack*s,int *x)

{//出栈

    if(s->top==-1)

    printf("Stack is empty!\n");

    else

    {

        *x=s->data[s->top];

        s->top--;

    }

}

void print(VertexNode g[],intve[],int v1[],int n)

{

    int i,j,e,l,dut;

    char tag;

    EdgeNode *p;

    printf("(vi,vj)dut最早开始时间  最晚开始时间  关键活动\n");

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

    for(p=g[i].firstedge;p!=NULL;p=p->next)

    {

        j=p->adjvex;

        dut=p->info;

        e=ve[i];

        l=v1[j]-dut;

        tag=(e==1)?'*':'';

        printf("(%d,%d)54d%11d%11d%8c\n",g[i].vertex,g[j].vertex,dut,e,tag);

    }

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

    printf("顶点%d的最早发生时间和最迟发生时间:%5d%5d\n",i,ve[i],v1[i]);

}

void CreatAdjlist(VertexNodeg[],int e,int n)

{//建立有向图的邻接表

    EdgeNode *p;

    int i,j,k,w;

    printf("Input data of (0~n-1);\n");

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

    {

        g[i].vertex=i;

        g[i].firstedge=NULL;

        g[i].indegree=0;

    }

    for(k=1;k<=e;k++)

    {

        printf("Input edgeof(i,j):");

        scanf("%d,%d",&i,&j);

        printf("Input weight of(%d,%d);",i,j);

        scanf("%d",&w);

        p=(EdgeNode *)malloc(sizeof(EdgeNode));

        p->adjvex=j;

        p->info=w;

        p->next=g[i].firstedge;

        g[i].firstedge=p;

        g[j].indegree=g[j].indegree+1;

    }

}

voidToplogicalorder(VertexNode g[],int n)

{//AOE网用邻接表存储,求各顶点事件最早发生时间

    int i,j,k,dut,count,*x=&j;

    int ve[MAXSIZE],v1[MAXSIZE];

    EdgeNode *p;

    SeqStack *s,*t;

    Init_SeqStack(&s);

    Init_SeqStack(&t);

    count=0;//顶点个数计数器

    for(i=0;i<n;i++)//初始化数组

    ve[i]=0;

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

     if(g[i].indegree==0)//初始化栈

       Push_SeqStack(s,i);

       while(!Empty_SeqStack(s))

       {

           Pop_SeqStack(s,x);//弹出零入度顶点

           Push_SeqStack(t,j);//将顶点j压入拓扑序列顶点栈

           count++;//对入栈t的顶点数计数

           p=g[j].firstedge;

           while(p!=NULL)//删除顶点j的所有边

           {

               k=p->adjvex;

               g[k].indegree--;//顶点j的邻接边结点k的入度减1

               if(g[k].indegree==0)

               Push_SeqStack(s,k);//顶点k入度减1后值为0则压入顶点栈s

               if(ve[j]+p->info>ve[k])

               ve[k]=ve[j]+p->info;//计算顶点事件的最早发生时间

               p=p->next;//查找顶点j的下一个邻接边结点

           }

       }

       if(count<n)//拓扑序列顶点未达到n时则AOE网有回路

       {

           printf("The AOE network has acycle!\n");

           goto L1;

       }

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

       v1[i]=ve[n-1];

       while(!Empty_SeqStack(t))//按拓扑排序的逆序求各顶点的v1值

       {

           Pop_SeqStack(t,x);//弹出拓扑排序顶点栈t中的顶点

          for(p=g[i].firstedge;p!=NULL;p=p->next)

           {//计算顶点事件的最迟事件

               k=p->adjvex;

               dut=p->info;

               if(v1[k]-dut<v1[j])

               v1[j]=v1[k]-dut;

           }

       }

       print(g,ve,v1,n);

       L1: ;

}

void main()

{

    int e,n;

    VertexNode g[MAXSIZE];

    printf("Input number ofnode:\n");

    scanf("%d",&n);

    printf("Input number of edge:\n");

    scanf("%d",&e);

    printf("Make adjlist :\n");

    CreatAdjlist(g,e,n);

    Toplogicalorder(g,n);//拓扑排序并求出关键路径

    printf("\n");

}

                                广度优先生成树

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct

{

    int data[MAXSIZE];//队中元素存储空间

    int rear,front;//队尾队头指针

}SeQueue;

void Int_SeQueue(SeQueue**q)//循环队列初始化

{

    *q=(SeQueue *)malloc(sizeof(SeQueue));

    (*q)->front=0;

    (*q)->rear=0;

}

int Empty_SeQueue(SeQueue*q)//判队空

{

    if(q->front==q->rear)

    return 1;

    else

    return 0;

}

void In_SeQueue(SeQueue*q,int x)//元素入队

{

    if((q->rear+1)%MAXSIZE==q->front)

    printf("Queue is full:\n");

    else

    {

        q->rear=(q->rear+1)%MAXSIZE;

        q->data[q->rear]=x;

    }

}

void Out_SeQueue(SeQueue*q,int *x)//出队

{

    if(q->rear==q->front)

    printf("Queue is empty!\n");

    else

    {

    q->front=(q->front+1)%MAXSIZE;

    *x=q->data[q->front];

}

}

typedef struct node      //邻接表结点

{

    int adjvex;//邻接点域

    struct node *next;

}EdgeNode;//邻接表结点类型

typedef struct vnode//顶点表结点

{

    int vertex;//顶点域

    EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域

}VertexNode;//顶点表结点类型

void CreatAdjlist(VertexNodeg[],int e,int n)//建立无向图的邻接表

{

    EdgeNode *p;

    int i,j,k;

    printf("Input date ofvetex(0~n-1):\n");

    for(i=0;i<n;i++)//建立有n个顶点的顶点表

    {

        g[i].vertex=i;//读入顶点i的信息

        g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针

    }

    for(k=1;k<=e;k++)

    {

        printf("Input edgeof(i,j):");

        scanf("%d,%d",&i,&j);

        p=(EdgeNode *)malloc(sizeof(EdgeNode));

        p->adjvex=j;

        p->next=g[i].firstedge;

        g[i].firstedge=p;

        p=(EdgeNode *)malloc(sizeof(EdgeNode));

        p->adjvex=i;//在顶点vj的邻接表中添加邻接点为i的结点

        p->next=g[j].firstedge;//插入在表头进行

        g[j].firstedge=p;

    }

}

int visited[MAXSIZE];

void BFSTree(VertexNodeg[],int i)//生成广度优先生成树

{

    int j,*x=&j;

    SeQueue *q;

    EdgeNode *p;

    visited[i]=1;

    Int_SeQueue(&q);

    In_SeQueue(q,i);//顶点i入队

    while(!Empty_SeQueue(q))

    {

        Out_SeQueue(q,x);//队头顶点出队并送j

        p=g[j].firstedge;//根据顶点j的表头指针查找其邻接表的第一个邻接边结点

        while(p!=NULL)

        {

           if(!visited[p->adjvex])//如果邻接的这个边结点未被访问过

            {

               printf("(%d,%d)",j,p->adjvex);//输出生成树中的一条边

                visited[p->adjvex]=1;//置邻接边结点未访问过标志

                In_SeQueue(q,p->adjvex);//将邻接边结点送入队q

            }

            p=p->next;//在顶点j的邻接表中查找j的下一个邻接边结点

        }

    }

}

void main()

{

    int e,n;

    VertexNode g[MAXSIZE];

    printf("Inoput number of node:\n");//输入图中结点个数

    scanf("%d",&n);

    printf("Input number ofedge:\n");//输入图中边的个数

    scanf("%d",&e);

    printf("Make adjlist:\n");

    CreatAdjlist(g,e,n);//建立无向图连接表

    printf("BFSTraverse:\n");

    BFSTree(g,0);//由顶点0开始生成广度优先生成树

    printf("\n");

}

                    建立无向图的邻接矩阵

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct

{

    charvertex[MAXSIZE];//顶点为字符型且顶点表的长度小于MAXSIZE

    intedges[MAXSIZE][MAXSIZE];//边为整形且edges为邻接矩阵

}MGraph;//采用邻接矩阵存储的图类型

void CreatMGraph(MGraph *g,int e,int n)

{//建立无向图的邻接矩阵

    int i,j,k;

    printf("Inputdata of vertex(0~n-1):\n");

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

    g->vertex[i]=i;//读入顶点信息

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

    for(j=0;j<n;j++)

    g->edges[i][j]=0;//初始化邻接矩阵

    for(k=1;k<=e;k++)//输入e条边

    {

        printf("Inputedge of (i,j):");

       scanf("%d,%d",&i,&j);

       g->edges[i][j]=1;

        g->edges[j][i]=1;

    }

}

void main()

{

    int i,j,n,e;

    MGraph *g;//建立指向采用邻接矩阵存储图类型的指针

    g=(MGraph*)malloc(sizeof(MGraph));//生成采用邻接矩阵存储类型的存储空间

    printf("Inputsize of MGraph:");//输入邻接矩阵的大小

   scanf("%d",&n);

    printf("Inputnumbers of edge:");//输入邻接矩阵的边数

   scanf("%d",&e);

    CreatMGraph(g,e,n);//生成存储图的邻接矩阵

    printf("OutputMGraph:\n");//输出存储图的邻接矩阵

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

    {

       for(j=0;j<n;j++)

       printf("%4d",g->edges[i][j]);

        printf("\n");

    }

}

                           每一对顶点间最短路径的Floyd算法

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 6

#define INF 32767

void Ppath(int path[][MAXSIZE],int i,int j)

{//前向递归查找路径上的顶点

    int k;

    k=path[i][j];

    if(k!=-1)//顶点vk不是起点

    {

        Ppath(path,i,k);//找顶点vi的前一个顶点vk

       printf("%d,",k);//输出顶点vk序号k

        Ppath(path,k,j);//找顶点vk的前一个顶点vj

    }

}

void Dispath(int A[][MAXSIZE],int path[][MAXSIZE],int n)

{

    int i,j;

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

    for(j=0;j<n;j++)

    if(A[i][j]==INF)

    {

        if(i!=j)

          printf("从%d到%d没有路径!\n",i,j);

    }

    else

    {

        printf("从%d到%d的路径长度: %d,路径: ",i,j,A[i][j]);

       printf("%d,",i);//输出路径上的起点序号

        Ppath(path,i,j);//输出路径上的各中间点序号

       printf("%d\n",j);//输出路径上的终点序号

    }

}

void Floyd(int gm[][MAXSIZE],int n)

{

    intA[MAXSIZE][MAXSIZE],path[MAXSIZE][MAXSIZE];

    int i,j,k;

    for(i=0;i<n;i++)//初始化

     for(j=0;j<n;j++)

     {

        A[i][j]=gm[i][j];//置初值

         path[i][j]=-1;//初始时表示没有中间顶点

     }

     for(k=0;k<n;k++)//按顶点编号k递增的次序查找当前顶点之间的最短路径

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

     if(A[i][j]>A[i][k]+A[k][j])

      {

         A[i][j]=A[i][k]+A[k][j];//从vi到vj经过vk时路径长度更短

          path[i][j]=k;//记录中间顶点vk的编号

      }

     Dispath(gm,path,n);//输出最短路径

}

void main()

{

    intg[MAXSIZE][MAXSIZE]={{INF,20,15,INF,INF,INF},{2,INF,INF,INF,10,30},{INF,4,INF,INF,INF,10},{INF,INF,INF,INF,INF,INF},{INF,INF,INF,5,INF,INF},{INF,INF,INF,4,10,INF}};

    Floyd(g,MAXSIZE);//求每一对顶点之间的最短路径

}

                         深度优先生成树

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node

{

    int adjvex;

    struct node *next;

}EdgeNode;

typedef struct vnode

{

    int vertex;//顶点域

    EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域

}VertexNode;//顶点表结点类型

void CreatAdjlist(VertexNode g[],int e,int n)//建立无向图的邻接表

{

    EdgeNode *p;

    int i,j,k;

    printf("Inputdata of vertex(0~n-1);\n");

    for(i=0;i<n;i++)//建立有n个顶点的顶点表

    {

        g[i].vertex=i;//读入顶点i信息

       g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针

    }

    for(k=1;k<=e;k++)//输入e条边

    {

        printf("Inputedge of(i,j):");

       scanf("%d,%d",&i,&j);

        p=(EdgeNode*)malloc(sizeof(EdgeNode));

        p->adjvex=j;

       p->next=g[i].firstedge;

        g[i].firstedge=p;

        p=(EdgeNode*)malloc(sizeof(EdgeNode));

        p->adjvex=i;//在顶点vj的邻接表中添加邻接点为j的结点

       p->next=g[i].firstedge;//插入在邻接表表头进行

        g[j].firstedge=p;

    }

}

int visited[MAXSIZE];

void DFSTree(VertexNode g[],int i)//图的深度优先搜索

{

    EdgeNode *p;

    visited[i]=1;//置顶点i为访问过标志

    p=g[i].firstedge;

    while(p!=NULL)//当邻接边结点不为空时

    {

       if(!visited[p->adjvex])//如果邻接的这个边结点未被访问过

        {

           printf("(%d,%d)",i,p->adjvex);//输出生成树中的一条边

           DFSTree(g,p->adjvex);//对这个结点进行深度优先搜索

        }

        p=p->next;//查找顶点i的下一个邻接边结点

    }

}

void DFSTraverse(VertexNode g[],int n)//生成深度优先生成树

{

    int i;

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

    visited[i]=0;//访问标志置0

    for(i=0;i<n;i++)//对n个顶点的图查找未访问过的顶点并由该节点开始遍历

    if(!visited[i])

    DFSTree(g,i);//comng未访问过的顶点i开始遍历

}

void main()

{

    int e,n;

    VertexNodeg[MAXSIZE];//定义顶点表结点类型数组

    printf("Inputnumber of node:\n");//输入图中结点个数

   scanf("%d",&n);

    printf("Inputnumber of edge:\n");//输入图中边的个数

   scanf("%d",&e);

    printf("Makeadjlist:\n");

    CreatAdjlist(g,e,n);//建立无向图连接表

   printf("DFSTraversre :\n");

    DFSTraverse(g,n);//生成深度优先生成树

   printf("\n");

}

                         图的广度优先搜索

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node1//邻接表结点

{

    int adjvex;//邻接域

    struct node1 *next;//指向下一个邻接边结点的指针域

}EdgeNode;//邻接表结点类型

typedef struct vnode//顶点表结点类型

{

    int vertex;//顶点域

    EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域

}VertexNode;//顶点表结点类型

void CreatAdjlist(VertexNode g[],int e,int n)//建立无向图的邻接表

{

    EdgeNode *p;

    int i,j,k;

    printf("Inputdata of vetex(0~n-1):\n");

    for(i=0;i<n;i++)//建立有n个顶点的顶点表

    {

        g[i].vertex=i;//读入顶点i信息

       g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针

    }

    for(k=1;k<=e;k++)//输入e条边

    {

        printf("Inputedge of(i,j):");

       scanf("%d,%d",&i,&j);

        p=(EdgeNode*)malloc(sizeof(EdgeNode));

        p->adjvex=j;//在顶点vi的邻接表中添加临界点为j的结点

       p->next=g[i].firstedge;//插入是在邻接表表头进行

        g[i].firstedge=p;

        p=(EdgeNode*)malloc(sizeof(EdgeNode));

        p->adjvex=i;//在顶点vj的邻接表中添加邻接点为i的结点

       p->next=g[j].firstedge;//在插入是在表头进行

        g[j].firstedge=p;

    }

}

typedef struct node

{

    int data;

    struct node *next;

}QNode;//链队列结点类型

typedef struct

{

    QNode *front,*rear;//将头、尾指针纳入到一个结构体的连队列

}LQueue;//链队列类型

void Init_LQueue(LQueue **q)//创建一个带头结点的空队列

{

    QNode *p;

    *q=(LQueue*)malloc(sizeof(LQueue));//申请队列

    p=(QNode*)malloc(sizeof(QNode));//申请链队列头结点

    p->next=NULL;//头结点的next指针置为空

    (*q)->front=p;//对头结点指针指向头结点

    (*q)->rear=p;//队尾指针指向头结点

}

int Empty_LQueue(LQueue *q)//判队空

{

   if(q->front==q->rear)

    return 1;

    else

    return 0;

}

void In_LQueue(LQueue *q,int x)//入队

{

    QNode *p;

    p=(QNode*)malloc(sizeof(QNode));//申请信新链队列结点

    p->data=x;

    p->next=NULL;//新结点作为队尾结点时其next域为空

   q->rear->next=p;//将新结点*p链到原队尾结点之后

    q->rear=p;//使队尾指针指向新的队尾结点*p

}

void Out_LQueue(LQueue *q,int *x)//出队

{

    QNode *p;

    if(Empty_LQueue(q))

    printf("Queue isempty!\n");

    else

    {

       p=q->front->next;//指针p指向链队列第一个数据结点

       q->front->next=p->next;//头结点的next指针指向链队列第二个数据结点

        *x=p->data;//将删除的头结点数据经x返回

        free(p);

       if(q->front->next==NULL)//出队后队为空,则值、置为空队列

       q->rear=q->front;

    }

}

int visited[MAXSIZE];

void BFS(VertexNode g[],LQueue *Q,int i)//广度优先搜索遍历邻接表存储图

{

    int j,*x=&j;

    EdgeNode *p;

   printf("%4d",g[i].vertex);//输出顶点i信息

    visited[i]=1;//置顶点i为访问过标志

    In_LQueue(Q,i);//顶点i入队Q

   while(!Empty_LQueue(Q))

    {

        Out_LQueue(Q,x);//队头顶点出队

       p=g[j].firstedge;//根据顶点j的表头指针查找其邻接表的第一个邻接边结点

        while(p!=NULL)

        {

           if(!visited[p->adjvex])//如果邻接的这个边未访问过

            {

               printf("%4d",g[p->adjvex].vertex);//输出邻接边的信息

               visited[p->adjvex]=1;//置邻接边访问过

               In_LQueue(Q,p->adjvex);//将该邻接边结点送入队Q

            }

           p=p->next;//在顶点的邻接表中查找下一个邻接边结点

        }

    }

}

void main()

{

    int e,n;

    VertexNodeg[MAXSIZE];//定义顶点表结点类型为数组

    LQueue *q;

    printf("Inputnumber of node:\n");//输入结点个数

   scanf("%d",&n);

    printf("Inputnumber of edge:\n");//输入图中边的个数

   scanf("%d",&e);

    printf("Makeadjlist :\n");

    CreatAdjlist(g,e,n);//建立无向图的邻接表

    Init_LQueue(&q);//队列初始化

   printf("BFSTraverse:\n");

    BFS(g,q,0);//广度优先遍历以邻接表存储的无向图

   printf("\n");

}

                                    图的连通性

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node1

{

    int adjvex;//邻接点域

    struct node1 *next;//指向下一个邻接边结点的指针域

}EdgeNode;//邻接边结点类型

typedef struct vnode

{

    int vertex;//顶点域

    EdgeNode *firstedge;//指向邻接表第一个

}VertexNode;//顶点表结点类型

void CreatAdjilist(VertexNode g[],int e,int n)//建立无向图的邻接表

{

    EdgeNode *p;

    int i,j,k;

    printf("Inputdata of vetex(0~n-1);\n");

    for(i=0;i<n;i++)//建立有n个顶点的顶点表

    {

        g[i].vertex=i;//读入顶点i信息

        g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针

    }

    for(k=1;k<=e;k++)//输入e条边

    {

        printf("Inputedge of(i,j):");

       scanf("%d,%d",&i,&j);

        p=(EdgeNode*)malloc(sizeof(EdgeNode));

        p->adjvex=j;//在顶点vi的邻接表中添加邻接点为j的结点

       p->next=g[i].firstedge;//插入在邻接表表头进行

        g[i].firstedge=p;

        p=(EdgeNode*)malloc(sizeof(EdgeNode));

        p->adjvex=i;

       p->next=g[j].firstedge;//在顶点vj的邻接表中添加邻接点为i的结点

        g[i].firstedge=p;

    }

}

int visited[MAXSIZE];//MAZSIZE为大于等于无向图顶点个数的常量

void DFS(VertexNode g[],int i)//图的深度优先遍历

{

    EdgeNode *p;

   printf("%4d",g[i].vertex);//输出顶点i信息

    visited[i]=1;//置i为访问过标志

    p=g[i].firstedge;//根据顶点i的指针查找其邻接表的第一个邻接边结点

    while(p!=NULL)

    {

       if(!visited[p->adjvex])//如果邻接点的这个边结点未被访问过

        DFS(g,p->adjvex);//对这个边结点进行深度优先搜索

        p=p->next;//查找顶点i的下一个邻接边结点

    }

}

int count=0;//连通分量计数初值为0

void ConnecgtEdge(VertexNode g[],int n)//深度优先搜索遍历

{

    int i;

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

    visited[i]=0;//访问标志置0

    for(i=0;i<n;i++)//对n个顶点的图查找未访问过的顶点并由该店开始遍历

    if(!visited[i])//当visited【i】等于0时即顶点i未访问过

    {

        DFS(g,i);//从未访问过的顶点i开始遍历

        count++;//访问过一个连通分量则count加一

    }

}

void main()

{

    int e,n;

    VertexNodeg[MAXSIZE];//定义顶点表结点类型数组

    printf("Inputnumber of node:\n");//输入图中结点的个数

   scanf("%d",&n);

    printf("Inputnumber of edge:\n");//输入图中边的个数

   scanf("%d",&e);

    printf("Makeadjlist :\n");

   CreatAdjilist(g,e,n);//建立无向图的邻接表

   printf("DFSTraverse:\n");

    ConnecgtEdge(g,n);//求图的连通分量

    printf("\nNumberof connect is %d\n",count);//输出连通分量

}

                               图的深度优先搜索

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node

{

    int adjvex;//邻接域

    struct node *next;//指向下一个邻接边结点的指针域

}EdgeNode;//邻接表结点类型

typedef struct vnode//顶点表结点

{

    int vertex;//顶点域

    EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域

}VertexNode;//顶点表结点类型

void CreatAdjlist(VertexNode g[],int e,int n)

{

    EdgeNode *p;

    int i,j,k;

    printf("Inputdata of vetex(0~n-1):\n");

    for(i=0;i<n;i++)//建立有n个顶点的顶点表

    {

        g[i].vertex=i;//读入顶点i信息

       g[i].firstedge=NULL;//初始化指向顶点i的邻接表表头指针

    }

    for(k=1;k<=e;k++)//输入e条边

    {

        printf("Inputedge of(i,j):");

       scanf("%d,%d",&i,&j);

        p=(EdgeNode*)malloc(sizeof(EdgeNode));

        p->adjvex=j;//在顶点vi的邻接表中添加结点为j的结点

       p->next=g[i].firstedge;//插入是在邻接表表头进行的

        g[i].firstedge=p;

        p=(EdgeNode*)malloc(sizeof(EdgeNode));

        p->adjvex=i;//在顶点vj的邻接表中添加邻接点为j的结点

       p->next=g[j].firstedge;//插入是在邻接表表头进行

        g[j].firstedge=p;

    }

}

int visited[MAXSIZE];//MAXSIZE为大于或等于无向图顶点个数的常量

void DFS(VertexNode g[],int i)

{

    EdgeNode *p;

   printf("%4d",g[i].vertex);//输出顶点i的信息

    visited[i]=1;//置顶点i为访问过标志

    p=g[i].firstedge;//根据顶点i的指针firstedge查找其邻接表的第一个邻接边结点

    while(p!=NULL)//当邻接边结点不为空

    {

       if(!visited[p->adjvex])//如果邻接的这个边结点未被访问过

       DFS(g,p->adjvex);//对这个边结点进行深度优先搜索

        p=p->next;//查找顶点i的下一个邻接边结点

    }

}

void DfSTraverse(VertexNode g[],int n)//深度优先搜索遍历以邻接表存储的图

{

    int i;

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

    visited[i]=0;//访问标志置0

    for(i=0;i<n;i++)//对n个顶点的图查找未访问过的顶点并由该顶点开始遍历

    if(!visited[i])//当visited[i]未被访问过

    DFS(g,i);//从未访问过的顶点i开始遍历

}

void main()

{

    int e,n;

    VertexNodeg[MAXSIZE];//定义顶点表结点类型数组g

    printf("Inputnumber of node:\n");//输入图中结点个数

   scanf("%d",&n);

    printf("Inputnumber of edge:\n");//输入图中边的个数

   scanf("%d",&e);

    printf("Makeadjlist :\n");

    CreatAdjlist(g,e,n);//建立无向图邻接表

   printf("DFSTraverse :\n");

    DfSTraverse(g,n);//深度优先遍历无向图

   printf("\n");

}

                             拓扑排序

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node //邻接表结点

{

    int adjvex;//邻接点域

    struct node *next;//指向下一个邻接边结点的指针域

}EdgeNode;//邻接表结点类型

typedef struct vnode//顶点表结点

{

    int indegree;//顶点入度

    int vertex;//顶点域

    EdgeNode *firstedge;//指向邻接表第一个邻接边结点的指针域

}VertexNode;//顶点表结构结点类型

void CreatAdjlist(VertexNode g[],int e,int n)

{//建立有向图的邻接表

    EdgeNode *p;

    int i,j,k;

    printf("Inputdata of vetex (0~n-1);\n");

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

    {

        g[i].vertex=i;

       g[i].firstedge=NULL;

        g[i].indegree=0;

    }

    for(k=1;k<=e;k++)

    {

        printf("Inputedge of(i,j):");

       scanf("%d,%d",&i,&j);

        p=(EdgeNode*)malloc(sizeof(EdgeNode));

        p->adjvex=j;

       p->next=g[i].firstedge;

        g[i].firstedge=p;

       g[j].indegree=g[j].indegree+1;

    }

}

void Top_Sort(VertexNode g[],int n)

{//用带有入度域的邻接表存储AOV网并输出一种拓扑排序,n为顶点个数

    int i,j,k,top,m=0;

    EdgeNode *p;

    top=-1;//栈顶指针初始化

    for(i=0;i<n;i++)//依次将入度为0的顶点链接成一个链栈

      if(g[i].indegree==0)

       {

          g[i].indegree=top;

           top=i;

       }

       while(top!=-1)

       {

           j=top;//取出栈顶入读为0 的一个顶点

          top=g[top].indegree;//栈顶指针指向弹栈后的下一个入读为0 的顶点

          printf("%d,",g[j].vertex);//输出刚弹出栈的结点j信息

           m++;//m记录已输出拓扑序列顶点个数

          p=g[j].firstedge;//根据顶点j的firstedge指针查其邻接表的第一个邻接边结点

          while(p!=NULL)//删除顶点j的所有边

           {

              k=p->adjvex;

              g[k].indegree--;//将顶点j的邻接边结点k入读减一

              if(g[k].indegree==0)//顶点k入读减1后若其值为0则将该顶点k链入链表

               {

                  g[k].indegree=top;

                   top=k;

               }

              p=p->next;//查找顶点j的下一个邻接边结点

           }

       }

       if(m<n)//输出顶点个数未达到n时则AOV网有回路

       printf("TheAOV network has a cycle!\n");

}

void main()

{

    int e,n;

    VertexNode g[MAXSIZE];

    printf("Inputnumber of node :\n");

   scanf("%d",&n);

    printf("Inputnumber of edge:\n");

   scanf("%d",&e);

    printf("Makeadjlist:\n");

    CreatAdjlist(g,e,n);

    printf("TopSort:\n");

    Top_Sort(g,n);//拓扑排序

   printf("\n");

}

                               最小生成树的Kruskal的算法

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

#define MAXCOST 32767

typedef struct

{

    int u;//边的起始顶点

    int v;//边的终止顶点

    int w;//边的权值

}Edge;

void Bubblesort(Edge R[],int e)//冒泡排序

{

    Edge temp;

    int i,j,swap;

    for(i=0;i<e-1;j++)

    {

        swap=0;//置未交换标志

       for(j=0;j<e-i-1;j++)

    if(R[j].w>R[j+1].w)

    {

       temp=R[j];R[j]=R[j+1];R[j+1]=temp;

        swap=1;//置有交换标志

    }

    if(swap==0)

    break;//本趟比较中未出现交换则结束排序

    }

}

void Kruskal(int gm[][6],int n)

{//构造最小生成树

    inti,j,u1,v1,sn1,sn2,k;

    int vest[MAXSIZE];

    EdgeE[MAXSIZE];//MAXSIZE为可存放边数的最大值

    k=0;

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

    for(j=0;j<n;j++)

   if(i<j&&gm[i][j]!=MAXCOST)//用数组E存储联通网中每条边的两个顶点及边上权值信息

    {

        E[k].u=i;

        E[k].v=j;

        E[k].w=gm[i][j];

        k++;

    }

    Bubblesort(E,k);//采用冒泡排序对数组E中的k条边按权值递增排序

    for(i=0;i<n;i++)//初始化辅助数组

    vest[i]=i;//给每个顶点置不同连通分量编号

 

    k=1;//k为当前构造生成树的第n条边,初值为1

    j=0;//数组E中元素下标,初值为0

    while(k<n)//产生最小生成树的n-1条边

    {

        u1=E[j].u;

        v1=E[j].v;//取一条边的头尾顶点

        sn1=vest[u1];

        sn2=vest[v1];

        if(sn1!=sn2)

        {//两定点分属于不同集合则为该边最小生成树的一条边

           printf("Edge:(%d,%d),Wight:%d\n",u1,v1,E[j].w);

            k++;//生成的变数加一

           for(i=0;i<n;i++)//俩个集合统一编号

           if(vest[i]==sn2)//集合编号为sn2的第i号边其编号改为是你sn1

            vest[i]=sn1;

        }

        j++;//扫描下一条边

    }

}

void main()

{

    intg[6][6]={{100,6,1,5,100,100},{6,100,5,100,3,100},{1,5,100,5,6,4},{5,100,5,100,100,2},{100,3,6,100,100,6},{100,100,4,2,6,100}};

    Kruskal(g,6);//生成最小生成树

}

                                   最小生成树的Prim算法

#include <stdio.h>

#include <stdlib.h>

#define MAXNODE 30

#define MAXCOST 32767

void Prim(int gm[][6],int closevertex[],int n)

{//建立最小生成树gm为邻接矩阵,n为顶点个数生成的最小生成素存储于closevertex中

    int lowcost[MAXNODE];

    int i,j,k,mincost;

    for(i=1;i<n;i++)

    {

       lowcost[i]=gm[0][i];//边u0~ui的权值送入lowcost【i】

       closevertex[i]=0;//假定顶点u1到顶点u0有一条边

    }

    lowcost[0]=0;//从序号为0的顶点出发生成最小生成树

    closevertex[0]=0;

    for(i=1;i<n;i++)//在n个顶点生成n-1条边的最小生成树

    {

        mincost=MAXCOST;//极大常量值

        j=1;k=0;

        while(j<n)//寻找未找到的最小权值边

        {

           if(lowcost[j]!=0&&lowcost[j]<mincost)

            {

               mincost=lowcost[j];//记下最小权值边的权值

                k=j;//记下最小权值边在v-u集中的顶点序号j

            }

            j++;

        }

       printf("Edge:(%d,%d),Wight:%d\n",k,closevertex[k],mincost);//输出最小生成树的边和权值

        lowcost[k]=0;//顶点k值进入u集

       for(j=1;j<n;j++)

       if(lowcost[j]!=0&&gm[k][j]<lowcost[j])

        {//若点k进入u集后顶点k和另一顶点j构成的边权值变小则改变lowcost[j]为这个小zhi

           lowcost[j]=gm[k][j];

           closevertex[j]=k;

        }

    }

}

void main()

{

    intclosevertex[MAXNODE];//存放最小生成树所有的边的数组

    intg[6][6]={{100,6,1,5,100,100,},{6,100,5,100,3,100},{1,5,100,5,6,4},{5,100,5,100,100,2},{100,3,6,100,100,6},{100,100,4,2,6,100}};

   Prim(g,closevertex,6);//生成最小生成树

}

/* * 基于邻接边表实现图的顶点结构 */ package dsa; public class Vertex_List implements Vertex { //变量 protected Object info;//当前顶点中存放的数据元素 protected Position vPosInV;//当前顶点在所属的图的顶点表V中的位置 protected List outEdges;//关联边表:存放以当前顶点为尾的所有边(的位置) protected List inEdges;//关联边表:存放以当前顶点为头的所有边(的位置) protected int status;//(在遍历图等操作过程中)顶点的状态 protected int dStamp;//时间标签:DFS过程中该顶点被发现时的时刻 protected int fStamp;//时间标签:DFS过程中该顶点被访问结束时的时刻 protected int distance;//到指定起点的距离:BFS、Dijkstra等算法所确定该顶点到起点的距离 protected Vertex bfsParent;//在最短距离树(BFS或BestFS)中的父亲 //构造方法:在图G中引入一个属性为x的新顶点 public Vertex_List(Graph G, Object x) { info = x;//数据元素 vPosInV = G.insert(this);//当前顶点在所属的图的顶点表V中的位置 outEdges = new List_DLNode();//出边表 inEdges = new List_DLNode();//入边表 status = UNDISCOVERED; dStamp = fStamp = Integer.MAX_VALUE; distance = Integer.MAX_VALUE; bfsParent = null; } //返回当前顶点的信息 public Object getInfo() { return info; } //将当前顶点的信息更新为x,并返回原先的信息 public Object setInfo(Object x) { Object e = info; info = x; return e; } //返回当前顶点的出、入度 public int outDeg() { return outEdges.getSize(); } public int inDeg() { return inEdges.getSize(); } //返回当前顶点所有关联边、关联边位置的迭代器 public Iterator inEdges() { return inEdges.elements(); } public Iterator inEdgePositions() { return inEdges.positions(); } public Iterator outEdges() { return outEdges.elements(); } public Iterator outEdgePositions() { return outEdges.positions(); } //取当前顶点在所属的图的顶点集V中的位置 public Position getVPosInV() { return vPosInV; } //读取、设置顶点的状态(DFS + BFS) public int getStatus() { return status; } public int setStatus(int s) { int ss = status; status = s; return ss; } //读取、设置顶点的时间标签(DFS) public int getDStamp() { return dStamp; } public int setDStamp(int s) { int ss = dStamp; dStamp = s; return ss; } public int getFStamp() { return fStamp; } public int setFStamp(int s) { int ss = fStamp; fStamp = s; return ss; } //读取、设置顶点至起点的最短距离(BFS) public int getDistance() { return distance; } public int setDistance(int s) { int ss = distance; distance = s; return ss; } //读取、设置顶点在的DFS、BFS、BestFS或MST树中的父亲 public Vertex getBFSParent() { return bfsParent; } public Vertex setBFSParent(Vertex s) { Vertex ss = bfsParent; bfsParent = s; return ss; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值