图顶点件路径间最短路径(广度遍历)

修改队列
文件Queue.h

#ifndef QUEUE_H_INCLUDED
#define QUEUE_H_INCLUDED
#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;
//改造队列
typedef struct Node{
    int data;
    //多加了一个前驱指针用于记录是谁的相邻顶点
    struct Node *next , *prior;
}Node;

typedef struct Queue{
    Node *head;
    Node *rear;
}Queue;

void Init(Queue &Q){
    //建一个不存数据的头结点
    Q.head = (Node*)malloc(sizeof(Node));
    Q.rear = Q.head;
    Q.head->next = Q.head->prior = NULL;
}
//push操作没改
void push(Queue &Q , int index){
    Node *p = (Node*)malloc(sizeof(Node));
    p->data = index;
    p->next = NULL;
    p->prior = Q.head;
    Q.rear->next = p;
    Q.rear = p;
}

int pop(Queue &Q){
    //只移动头指针不做元素删除
    Q.head = Q.head->next;
    return Q.head->data;
}

bool empty(Queue &Q){
    if(Q.head != Q.rear){
        return false;
    }
    else{
        return true;
    }
}
#endif // QUEUE_H_INCLUDED

图结构
Graph.h

#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include <iostream>
#include <cstdlib>
#include "Queue.h"

using namespace std;
//链表结构
typedef struct ListNode {
    int index;
    struct ListNode *next;
}ListNode;
//顶点结构
typedef struct Vertex{
    ListNode *firstvex;
    char data;
}Vertex;
//图结构
typedef struct Graph{
    Vertex vertex[256];
    int vexnum , edgenum;
}Graph;

void Init(Graph &G);
void Create_Graph(Graph &G);
void BFSTraverse(Graph G , char x , char y);

void Init(Graph &G){
    G.edgenum = 0;
    G.vexnum = 0;
}

void Create_Graph(Graph &G){
    cout << "请输入顶点数:" ;
    cin >> G.vexnum;
    cout << "请输入边数:";
    cin >> G.edgenum;
    int i , j , k;
    //第0号位置不用,输入顶点
    for (i = 1 ; i <= G.vexnum ; i++){
        cout << "第" << i << "个顶点为:";
        cin >> G.vertex[i].data;
        G.vertex[i].firstvex = NULL;
    }
    //输入边
    for(int k = 0 ; k < G.edgenum ; k++){
        cout << "请输入边(vi , vj)的下标i,j:";
        cin >> i >> j;
        //构造边即将顶点下标存入链结构中
        //前插法,尾插法需要遍历好麻烦
        ListNode *e = new ListNode;
        e->index = j;
        e->next = G.vertex[i].firstvex;
        G.vertex[i].firstvex = e;

        e = new ListNode;
        e->index = i;
        e->next = G.vertex[j].firstvex;
        G.vertex[j].firstvex = e;
    }
}
//是否访问的标志
int visited[256];
//x , y 即用户想要查找从x到y的最短路径
void BFSTraverse(Graph G , char x , char y){
    Queue Q;
    Init(Q);
    int i;
    for(i = 1 ; i <= G.vexnum ; i++){
        visited[i] = 0;
    }
    //用于存放用户指定的开始点下标
    int start;
    //获得顶点x对应的下标
    for(i = 1 ; i <= G.vexnum ;i++){
        if(G.vertex[i].data == x){
            start = i;
            break;
        }
    }
    if(visited[start] == 0){
        visited[start] = 1;
        //将开始点如队列
        push(Q , start);
        while(!empty(Q)){
            int index = pop(Q);
            //w指向队头元素相邻的第一个元素
            ListNode *w = G.vertex[index].firstvex;
            //然后一直将栈顶元素所有相邻顶点遍历完
            //再到相邻顶点遍历
            while(w){
                if(visited[w->index] == 0){
                    visited[w->index] = 1;
                    //将相邻点入队
                    push(Q , w->index);
                }
                //如果相邻点就是要到的终点
                if(G.vertex[w->index].data == y){
                    //p指向的就是终点
                    Node *p = Q.rear;
                    cout << x << "-->" << y << "的路径为:";
                    //有终点向前遍历到起点
                    while(G.vertex[p->data].data != x){
                        cout << G.vertex[p->data].data;
                        p = p->prior;
                    }
                    //输出起点
                     cout << x;
                     //直接结束
                     return;
                }
                w = w->next;
            }
        }
    }

}
void ShortPath(Graph G){
    char x , y;
    cout << "请输入你需要查找最短路径的两顶点:";
    cin >> x >> y;
    //将x和y掉换位置是因为输出是逆序输出,用队列元素的prior
    //指针向前遍历得到即y-->x,调换后就是正序输出x-->y
    BFSTraverse(G , y , x);
}
#endif // GRAPH_H_INCLUDED

main.cpp

#include <iostream>
#include "Graph.h"

using namespace std;
int main()
{
    Graph G;
    Init(G);
    Create_Graph(G);
    ShortPath(G);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值