数据结构与算法/图的应用

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

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

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

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

实现上述两个功能时要求图分别用邻接矩阵和邻接表表示。求简单路径问题,可利用图得深度优先搜索遍历算法实现,从顶点 i 出发,开始遍历,访问到顶点 j 时遍历结束。在遍历的过程中,需要将访问过的顶点压入栈,当在遍历过程中遇到一个访问过的顶点 k 时,需要依次删除栈中元素,直到栈顶为 k。遍历结束后,将栈中的顶点倒着输出即为顶点 i 到顶点 j 的简单路径。

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

#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.top = S.base;

    S.stacksize = 100;

    return OK;

}

Status Push(SqStack &S,VerTexType e)

{

    if(S.top - S.base == S.stacksize)return ERROR;

    *S.top++ = e;

    return OK;

}

Status Pop(SqStack &S,VerTexType &e)

{

    if(S.top == S.base)return 0;

    VerTexType *temp;

    temp = S.top;

    S.top--;

    delete temp;

    e = *S.top;

    return OK;

}

void ShowStack(SqStack &S)

{

    VerTexType *top = S.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<<"到"<<*(S.top-1)<<"的路径为:";

    while(S.top!=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;

 

}



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值