我写的这个算法跟一般的dijkstra算法不一样,我这里定义了一个map[100][100],以他为地图再自己手动定义起始点和终点,进行最短路径的寻找。
#include<iostream>
using namespace std;
struct node
{
int elem;//作为标志起点终点障碍物的标志,最后输出的就是他
bool sy;//做为节点访问的标志
bool sy1;//作为节点遍历的标志
int dist;//长度
};
struct node1
{
int x;int y;
};
node map[100][100];
node1 c[500];//存一些没有访问的数的坐标
node1 d[500];//这是c数组的一个承接
int maxint=20;//最后要输出的边长,图的大小
class dij
{
private:
int stax,stay,endx,endy;//起始坐标,终点坐标
public:
dij(int x1,int y1,int x2,int y2);
dij();
~dij();
void search();
int sum(int x,int y,int su);//遍历周围节点
void output();
};
dij::dij(int x1,int y1,int x2,int y2)
{
int i,j;
stax=x1,stay=y1,endx=x2,endy=y2;
for(i=0;i<maxint;i++)//初始化
for(j=0;j<maxint;j++)
{
map[i][j].elem=0;
map[i][j].sy=false;
map[i][j].sy1=false;
map[i][j].dist=1;//两点之间的最短路径为1
}
map[x1][y1].elem=2;
map[x2][y2].elem=3;
for(i=4;i<15;i++)//手动的障碍物
map[10][i].elem=1;
}
dij::dij()
{
stax=stay=endx=endy=0;
}
dij::~dij()
{
}
void dij::search()
{
int m=1,i,su=0,flag=0,temp=999999;
c[0].x=stax,c[0].y=stay;
while(1)
{
for(i=0;i<m;i++)//访问c数组中的节点
{
temp=999999;//这段主要是为了找到周围被访问过的节点的最短路径+1,就是这个路径的最短路径
if(map[c[i].x][c[i].y].elem==3)
{flag=1;break;}
map[c[i].x][c[i].y].sy=true;//表示节点已访问
if(c[i].x-1>-1&&map[c[i].x-1][c[i].y].sy==true&&map[c[i].x-1][c[i].y].dist<temp)
temp=map[c[i].x-1][c[i].y].dist;
if(c[i].x+1<maxint&&map[c[i].x+1][c[i].y].sy==true&&map[c[i].x+1][c[i].y].dist<temp)
temp=map[c[i].x+1][c[i].y].dist;
if(c[i].y-1>-1&&map[c[i].x][c[i].y-1].sy==true&&map[c[i].x][c[i].y-1].dist<temp)
temp=map[c[i].x][c[i].y-1].dist;
if(c[i].y+1<maxint&&map[c[i].x][c[i].y+1].sy==true&&map[c[i].x][c[i].y+1].dist<temp)
temp=map[c[i].x][c[i].y+1].dist;
if(temp!=999999)
map[c[i].x][c[i].y].dist=temp+1;
su=sum(c[i].x+1,c[i].y,su);//遍历上
su=sum(c[i].x-1,c[i].y,su);//下
su=sum(c[i].x,c[i].y+1,su);//右
su=sum(c[i].x,c[i].y-1,su);//左
}
if(flag==1)
break;
for(i=0;i<su;i++)
{
c[i].x=d[i].x;//将d中的值给c中
c[i].y=d[i].y;
}
m=su;
su=0;
}
}
int dij::sum(int x,int y,int su)//遍历周围节点,将sy1设为true
{
if(map[x][y].elem!=1&&x>-1&&x<maxint&&y>-1&&y<maxint&&map[x][y].sy==false&&map[x][y].sy1==false)
{
map[x][y].sy1=true;
d[su].x=x;d[su].y=y;
su++;
}
return su;
}
void dij::output()//从终点往回找,遍历已被访问过的周围节点,找到一个到起点距离最小的值,接着从那个节点继续往下找,只到找到终点为止
{
int x1,y1,x,y;int temp=999999;
x=endx;
y=endy;
while(1)
{
if(x-1>0&&map[x-1][y].sy==true&&map[x-1][y].dist<temp)
{
x1=x-1,y1=y;
temp=map[x-1][y].dist;
}
if(x+1<maxint&&map[x+1][y].sy==true&&map[x+1][y].dist<temp)
{
x1=x+1,y1=y;
temp=map[x+1][y].dist;
}
if(y-1>0&&map[x][y-1].sy==true&&map[x][y-1].dist<temp)
{
x1=x,y1=y-1;
temp=map[x][y-1].dist;
}
if(y+1<maxint&&map[x][y+1].sy==true&&map[x][y+1].dist<temp)
{
x1=x,y1=y+1;
temp=map[x][y+1].dist;
}
x=x1,y=y1;
if(map[x][y].elem==2)
break;
map[x][y].elem=7;//将路径设为7
}
int i,j;
for(i=0;i<maxint;i++)
{
for(j=0;j<maxint;j++)
{
cout<<map[i][j].elem<<" ";
}
cout<<endl;
}
}
int main()
{
int x1,y1,x2,y2;
cout<<"输入两个数的坐标作为起点"<<endl;
cin>>x1>>y1>>x2>>y2;
dij a(x1,y1,x2,y2);
a.search();
a.output();
return 0;
}
可以直接运行,手动设定的障碍物在map[10][4]~map[10][14],注意不要把起点建在障碍物上。