//注:我这段代码预先输入好了值,图有机会贴上来

1、掌握图的各种存储结构的特点及适用范围。

2、掌握建立图的方法。(包括邻接矩阵、邻接表)

3、熟练掌握图的深度优先搜索算法和广度优先搜索算法,并能灵活运用这两个算法解决实际问题。

实现上述两个功能时要求图分别用邻接矩阵和邻接表表示。求简单路径问题,可利用图得深度优先搜索遍历算法实现,从顶点

求最短路径问题,可利用图得广度优先搜索遍历算法实现,为实现图得广度优先搜索算法,需要用到队列。


#include <stdio.h>
#include <iostream>
#include <setjmp.h>
using namespace std;
#define MaxInt 32767//表示正无穷
#define MVNum 100//最大顶点数
#define OK 1
#define ERROR -1
#define OVERFLOW -2
jmp_buf j;
typedef int Status;
typedef char VerTexType;//假设顶点的数据类型为字符型
typedef int ArcType;//假设边的权值类型为整型
typedef int OtherInfo;
typedef struct QNode
{
    VerTexType data;
    struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;
typedef struct
{
    VerTexType vexs[MVNum];//顶点表
    ArcType arcs[MVNum][MVNum];//邻接矩阵
    int vexnum,arcnum;//图的当前点数和边数
}AMGraph;
 
typedef struct stack
{
    VerTexType *base;
    VerTexType *top;
    int stacksize;
}SqStack;
typedef struct ArcNode
{
    int adjvex;//该边所指向的顶点的位置
    struct ArcNode *nextarc;//指向下一条边的指针
    OtherInfo info;//边的信息
}ArcNode;
typedef struct VNode
{
    VerTexType data;
    ArcNode *firstarc;//指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum];//表示邻接表类型
typedef struct
{
    AdjList vertices;//图的当前顶点数和边数
    int vexnum,arcnum;
}ALGraph;
int path[6][6];
bool isVisited[MaxInt];
SqStack S;
LinkQueue Q;
int D[6][6];
int anopath[6][6];
char PreChar[6]={'a','b','c','d','e','f'};
//void DFS_AM(AMGraph &G,VerTexType v1,VerTexType v2);
void InitQueue(LinkQueue &Q )//初始化队列
{
    Q.front = Q.rear = new QNode;
    Q.front->next = NULL;
    return;
}
 
void EnQueue( LinkQueue &Q, VerTexType x)//尾插法入队,将x存储在Q链表的尾部
{
    QNode *p = new QNode;    //申请新结点
    p->data=x; //将x存入p中的数据域
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return;
}
int DeQueue( LinkQueue &Q,VerTexType &x)//出队操作,将在最前面的元素出队
{
    if(Q.front == Q.rear)return 0;
    QNode *p=Q.front->next;//将Q的队列头元素地址赋给p
    //p 指向将要摘下的结点
    x=p->data; //保存结点中数据
    Q.front->next = p->next;//令p的下一节点指向第一个元素
    if (p==Q.rear)//如果队列为空
    {
        Q.rear = Q.front;//当队列中只有一个结点时,p 结点出队后, 要将队尾指针指向头结点
    }
    delete p;//释放被删结点
    return 1;
}
void ShowQueue(LinkQueue &Q)//显示所有元素
{
    if(Q.front->next == NULL)//如果队列中无元素
    {
        printf("无元素");
        return;
    }
    QNode* p=Q.front->next;//令p指针指向第一个元素
    do//当p遍历所有结点时
    {
        printf("%c ",p->data);//输出队列中所有元素
        p = p->next;//p指向下一元素
    }while(p!=Q.rear->next);
    getchar();
    return;
}
Status CreateUDN (AMGraph &G)//用邻接矩阵创建有向网P154 图6.10(a)
{
    G.vexnum = 6;
    G.arcnum = 10;
    cout<<"总点数为:"<<G.vexnum<<endl;
    cout<<"总边数为:"<<G.arcnum<<endl;
    cout<<"依次输入点的信息:"<<endl;
    G.vexs[0] = 'a';//v1
    G.vexs[1] = 'b';//v2
    G.vexs[2] = 'c';//v3
    G.vexs[3] = 'd';//v4
    G.vexs[4] = 'e';//v5
    G.vexs[5] = 'f';//v6
    for(int i = 0;i<G.vexnum;i++)
        cout<<G.vexs[i]<<endl;
    for(int i = 0;i<G.vexnum;i++)//初始化邻接矩阵使边的权值均为MAXINT
        for(int j = 0;j<G.vexnum;j++)
            G.arcs[i][j] = MaxInt;
    G.arcs[0][1] = 5;G.arcs[0][3] = 7;
    G.arcs[1][2] = 4;G.arcs[2][0] = 8;
    G.arcs[2][5] = 9;G.arcs[3][2] = 5;
    G.arcs[3][5] = 6;G.arcs[4][3] = 5;
    G.arcs[5][0] = 3;G.arcs[5][4] = 1;
 
    for(int i =0;i<G.vexnum;i++)
    {
        for(int j = 0;j<G.vexnum;j++)
        {
            cout<<"\t"<<G.arcs[i][j];
        }
        cout<<endl;
    }
    return OK;
}
Status InitStack (SqStack &S)
{
    S.base = new VerTexType[100];
    if(!S.base)cout<<"ERROR";
     = S.base;
    S.stacksize = 100;
    return OK;
}
Status Push(SqStack &S,VerTexType e)
{
    if( - S.base == S.stacksize)return ERROR;
    *++ = e;
    return OK;
}
Status Pop(SqStack &S,VerTexType &e)
{
    if( == S.base)return 0;
    VerTexType *temp;
    temp = ;
    --;
    delete temp;
    e = *;
    return OK;
}
void ShowStack(SqStack &S)
{
    VerTexType *top = ;
    while(S.base != top)
    {
        cout<<*(--top)<<" ";
    }
    cout<<"over "<<endl;
}
int GetIndex(AMGraph &G,VerTexType v)
{
    int index = -1;
    for(int i=0;i<G.vexnum;i++)
    {
        if(v == G.vexs[i]){return i;}//获取v1下标
    }
    return index;
}
void DFS_AM(AMGraph &G,VerTexType v1,VerTexType v2)
{
    Push(S,v1);
    if(v1 == v2)
    {
        longjmp(j,1);
    }
    isVisited[GetIndex(G,v1)] = true;
    for(int w = 0;w<G.vexnum;w++)
    {
        if(G.arcs[GetIndex(G,v1)][w]!=MaxInt && (isVisited[w]==false))DFS_AM(G,G.vexs[w],v2);
    }
 
}
void CreateAdjList(ALGraph &G)
 {
     G.vexnum = 6;G.arcnum=10;
     for(int i =0;i<G.vexnum;i++)
     {
            G.vertices[i].data = PreChar[i];//输入顶点值
            G.vertices[i].firstarc = NULL;
            G.vertices[i].firstarc = new ArcNode;G.vertices[i].firstarc->nextarc = new ArcNode;G.vertices[i].firstarc->nextarc->nextarc = new ArcNode;G.vertices[i].firstarc->nextarc->nextarc->nextarc = new ArcNode;G.vertices[i].firstarc->nextarc->nextarc->nextarc->nextarc = new ArcNode;
     }
    G.vertices[0].firstarc->adjvex = 1;G.vertices[0].firstarc->info = 3;G.vertices[0].firstarc->nextarc->adjvex = 4;G.vertices[0].firstarc->nextarc->info = 4;G.vertices[0].firstarc->nextarc->nextarc = NULL;
    G.vertices[1].firstarc->adjvex = 0;G.vertices[1].firstarc->info = 3;G.vertices[1].firstarc->nextarc->adjvex = 4;G.vertices[1].firstarc->nextarc->info = 9;G.vertices[1].firstarc->nextarc->nextarc->adjvex = 5;G.vertices[1].firstarc->nextarc->nextarc->info = 5;G.vertices[1].firstarc->nextarc->nextarc->nextarc->adjvex = 2;G.vertices[1].firstarc->nextarc->nextarc->nextarc->info = 4;G.vertices[1].firstarc->nextarc->nextarc->nextarc->nextarc = NULL;
    G.vertices[2].firstarc->adjvex = 3;G.vertices[2].firstarc->info = 2;G.vertices[2].firstarc->nextarc->adjvex = 5;G.vertices[2].firstarc->nextarc->info = 7;G.vertices[2].firstarc->nextarc->nextarc->adjvex = 1;G.vertices[2].firstarc->nextarc->nextarc->info = 4;G.vertices[2].firstarc->nextarc->nextarc->nextarc = NULL;
    G.vertices[3].firstarc->adjvex = 2;G.vertices[3].firstarc->info = 2;G.vertices[3].firstarc->nextarc->adjvex = 5;G.vertices[3].firstarc->nextarc->info = 6;G.vertices[3].firstarc->nextarc->nextarc->adjvex = 4;G.vertices[3].firstarc->nextarc->nextarc->info = 2;G.vertices[3].firstarc->nextarc->nextarc->nextarc = NULL;
    G.vertices[4].firstarc->adjvex = 0;G.vertices[4].firstarc->info = 4;G.vertices[4].firstarc->nextarc->adjvex = 1;G.vertices[4].firstarc->nextarc->info = 9;G.vertices[4].firstarc->nextarc->nextarc->adjvex = 3;G.vertices[4].firstarc->nextarc->nextarc->info = 2;G.vertices[4].firstarc->nextarc->nextarc->nextarc->adjvex = 5;G.vertices[4].firstarc->nextarc->nextarc->nextarc->info = 2;G.vertices[4].firstarc->nextarc->nextarc->nextarc->nextarc = NULL;
    G.vertices[5].firstarc->adjvex = 1;G.vertices[5].firstarc->info = 5;G.vertices[5].firstarc->nextarc->adjvex = 2;G.vertices[5].firstarc->nextarc->info = 7;G.vertices[5].firstarc->nextarc->nextarc->adjvex = 3;G.vertices[5].firstarc->nextarc->nextarc->info = 6;G.vertices[5].firstarc->nextarc->nextarc->nextarc->adjvex = 4;G.vertices[5].firstarc->nextarc->nextarc->nextarc->info = 2;G.vertices[5].firstarc->nextarc->nextarc->nextarc->nextarc = NULL;
 
     for(int i = 0;i<G.vexnum;i++)
    {
        cout<<i<<"\t"<<G.vertices[i].data<<"\t->";
        ArcNode *p = G.vertices[i].firstarc;
        while(p!=NULL)
        {
            cout<<"\t"<<p->adjvex<<"\t"<<p->info<<"\t";
            p = p->nextarc;
 
        }
        cout<<endl;
    }
 
}
//a->e  最短4 最长3+9 = 12
int GetIndex1(ALGraph G,VerTexType v)
{
    for(int i = 0 ;i<G.vexnum;i++)
    {
        if(G.vertices[i].data == v)return i;
    }
    cout<<"wrong index";
}
Status CreateMatrix (ALGraph &G)
{
    for( int i = 0;i<G.vexnum;i++)
    {
        ArcNode *p = G.vertices[i].firstarc;
        while(p!=NULL)
        {
            int j = p->adjvex;
            path[i][j] = p->info;
//            cout<<"path"<<i<<j<<"="<<path[i][j];
            p = p->nextarc;
        }
 
    }
    cout<<endl;
 
 
}
 
void ShortertPath_Floyd(ALGraph &G)
{
for(int i = 0;i<G.vexnum;i++)
    {
        for(int j = 0;j<G.vexnum;j++)
            {
                if(i!=j&&path[i][j]==0)path[i][j]=100;
            }
        cout<<endl;
    }
    for(int  i =0;i<G.vexnum;i++)
        {
            for(int j=0;j<G.vexnum;j++)
            {
                D[i][j] = path[i][j];
                if(D[i][j]<100&&i!=j)anopath[i][j]= i;
                else anopath[i][j] = -1;
            }
        }
//    for(int i = 0;i<G.vexnum ;i++)
//    {
//        for(int j = 0;j<G.vexnum;j++)
//            cout<<anopath[i][j]<<"\t";
//            cout<<endl;
//    }
    for(int k = 0;k<G.vexnum;++k)
        {
            for(int i = 0;i<G.vexnum;++i)
            for(int j = 0;j<G.vexnum ;++j)
            {
                if(D[i][k]+D[k][j]<D[i][j])
                    {
//                        cout<<D[i][j];
                        D[i][j] = D[i][k]+D[k][j];
//                        cout<<D[i][j]<<endl;
                    anopath[i][j] = anopath[k][j];
                    }
            }
 
        }
 
}

 

 

 

int main()
{
    //邻接矩阵部分
    InitQueue (Q) ;
    AMGraph G;
    InitStack(S);
    CreateUDN(G);
 
    if(setjmp(j) == 0)
    {
        DFS_AM(G,G.vexs[1],G.vexs[0]);
    }
    else
    {
    }
    char ch[100];
    int flag = 0;
    cout<<"从"<<*S.base<<"到"<<*(-1)<<"的路径为:";
    while(!=S.base)
    {
        Pop(S,ch[flag]);
    //        cout<<ch[flag]<<" ";
        flag++;
    }
 
    for(int i = flag;i>=0;i--)
    {
        cout<<ch[i]<<" ";
    }
    cout<<endl;
    //邻接表部分
    for(int i = 0;i<10;i++)//初始化isvisited数组
    {
        isVisited[i]=false;
    }
    ALGraph GG;
    CreateAdjList(GG);
    for(int i = 0;i<GG.vexnum;i++)
    {
        cout<<i<<"\t"<<GG.vertices[i].data<<"\t->";
        ArcNode *p = GG.vertices[i].firstarc;
        while(p!=NULL)
        {
            cout<<"\t"<<p->adjvex<<"\t"<<p->info<<"\t";
            p = p->nextarc;
        }
        cout<<endl;
    }
    CreateMatrix(GG);
 
    ShortertPath_Floyd(GG);
                cout<<"D[i][j]图如下:"<<endl;
    for(int i = 0;i<G.vexnum ;i++)
    {
        for(int j = 0;j<G.vexnum;j++)
            cout<<D[i][j]<<"\t";
            cout<<endl;
    }
    int i = 1,j = 5;
    cout<<"从"<<i+1<<"到"<<j+1<<"的最短路径长度为:"<<D[i][j];
    return 0;
 
}