//注:我这段代码预先输入好了值,图有机会贴上来
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;
}