修改队列
文件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);
}