关于寻找最短路径类似的dijkstra

我写的这个算法跟一般的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],注意不要把起点建在障碍物上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值