Dijstra___java版

本文详细介绍了使用C语言实现Dijkstra算法的过程,包括节点类的定义和主要思想实现部分。通过创建和操作节点,进行数据添加、删除、查找等操作,并应用到Dijkstra算法中寻找最短路径。代码清晰,注重算法思想的阐述。

具体内容思想看,我用C已经很详细的将结果了。思想都是一样的 。语言只不过是实现的一个工具。要注意思想。

本文只是为了上传代码。

 

 

这是链接

https://blog.youkuaiyun.com/Bkhole/article/details/116212036

 

 

代码如下:

第一部分为结点类

package algorithmTest;

/**
 * @Auther: 张JJ
 * @Date: 2021/4/28 - 04 - 28 - 11:25
 * @Description: algorithmTest
 * @version: 1.0
 */
public class Node {
//数据结点定义
/*数据类型说明:
无穷大:INF = 65536; 0表示不关联
* */

    int INF = 65536;
    char name[] ;
    int sum[];
    private int len;

    public int getLen() {
        return len;
    }

    public void setLen(int len) {
        this.len = len;
    }

    public Node(char name, int sum) {
        this.name = new char[1];
        this.sum = new int[1];
        this.name[0] = name;
        this.sum[0] = sum;
        this.setLen(1);
    }

    public Node() {

    }

    //节点初始化
    public Node(int len) {
        name = new char[len+1];
        sum = new int[len+1];
        for (int i = 0; i < len; i++) {
            this.name[i] = (char)(65+i);
            this.sum[i] = INF ;
        }
        this.len = len;
    }
    //数据删除--0--按name删除
    public void Delete(char name){
        int i =0;
        int len =this.getLen();
        while (this.name[i] != name)
        {
            i++;
        }
        for (; i < len; i++) {
            this.name[i] = this.name[i+1];
            this.sum[i] = this.sum[i+1];
        }
        setLen(getLen()-1);
    }
    //数据删除--1--按sum删除
    public void Delete(int sum){
        int i =0;
        while (this.sum[i] != sum)
        {
            i++;
        }
        for (; i < this.len; i++) {
            this.name[i] = this.name[i+1];
            this.sum[i] = this.sum[i+1];
            setLen(getLen()-1);
        }
    }
    //数据添加--0--
    public void add(char name, int sum) {
        int len =this.getLen();
        this.name[len] = name;
        this.sum[len]  = sum;
        this.setLen(len+1);
    }
    //最小值---》按sum取
    public Node Min(){
        int len=this.getLen();
        Node min = new Node('s',INF);
        for (int i = 0; i < len; i++) {
            if (this.sum[i] < min.sum[0]){
                min.sum[0] =sum[i];
                min.name[0] = name[i];
            }
        }
        return min;
    }
    //获取最小值下标
    public int Idmin(){
        int i = 0;
        for ( i = 0; i < this.getLen(); i++) {
            if (this.sum[i] > this.sum[i + 1])
            {
                i = i+1;
            }

        }
        return i;
    }
    //以 标号 指定对应的name
    public char getName(int i) {
        char c='0';//随意给的值,占位
        switch (i){
            case 0:c=  'A';break;
            case 1:c=  'B';break;
            case 2:c=  'C';break;
            case 3:c=  'D';break;
            case 4:c=  'E';break;
        }
        return c;
    }
    //获取对应标号  ----》0:A,1:B.....
    public int getId(char name){
        int i = -1;
        switch (name){
            case 'A':i = 0;break;
            case 'B':i = 1;break;
            case 'C':i = 2;break;
            case 'D':i = 3;break;
            case 'E':i = 4;break;
        }
        return i;
    }
    //修改sum
    public void Update(char name,int sum){
        int i =0;
        while (this.name[i] != name )
        {
            i++;
        }
        this.sum[i] = sum;
    }
    //根据name返回在数组中的下标值
    public int IDname(char name){
        int i = 0;
        for ( i = 0; i < this.getLen(); i++) {
            if (this.name[i] == name)
            {
                break;
            }
            i++;
        }
        return i;
    }


}

第二部分为main函数 主要思想实现部分

package algorithmTest;

/**
 * @Auther: 张JJ
 * @Date: 2021/4/27 - 04 - 27 - 10:28
 * @Description: algorithmTest
 * @version: 1.0
 */
public class DIjstra02 {
    public static void main(String[] args) {
        //顶点个数
        int V = 5;
        int t[][] = {
                {0, 1000, 2, 5, 4},
                {1000, 0, 1, 3, 3},
                {2, 1, 0, 4, 2},
                {5, 3, 4, 0, 1000},
                {4, 3, 2, 1000, 0}
        };
        int i = 0, j, k=0;
        Node S = new Node(V);//已知起点到k点的最短距离
        Node U = new Node(V);//记录还未求出最短路径的顶点(以及该顶点到起点s的距离)
        Node s = new Node();//一个临时结点,用来储存最小值得结点---》包含name,sum
        //定义一个最小路径顶点的父节点 从而避免在循环的过程中反复遍历遍历过的点
        Node sFather =new Node(1) ;
        sFather.name[0] = 'z';//随意定义,目的避免出现遍历确实---》这个随意定义的字符必须是顶点数组中没有的
        //设置起点---》(A,0)
        char Frist = 'A';
        for (int l = 0; l < V; l++) {
            char s0 = S.name[l];
            if (s0 == Frist) {
                S.sum[l] = 0;
                continue;
            }
            S.name[l] = S.name[l + 1];
            S.sum[l] = S.sum[l + 1];
            S.setLen(S.getLen() - 1);
        }
        U.Delete(Frist);
        //----------------
        s = U.Min();
        char s0 =s.name[0] = 'z';
        for (int l = 0; l <V ; l++) {

            for (int m = 0; m < V; m++) {
                if (t[k][m] == 1000 ||t[k][m]==0||m==sFather.getId(sFather.name[0])){
                    continue;
                }
                int q = 0;
                if (l == 0)
                {
                    q = t[k][m];
                    U.Update(U.getName(m),q);
                }
                else if (t[k][m]+s.sum[0] < U.sum[U.IDname(U.getName(m))]){
                    q = t[k][m]+s.sum[0];
                    U.Update(U.getName(m),q);
                }
            }
            //更新最小值结点
            s = U.Min();
            //更新父节点
            sFather.name[0] = S.name[S.getLen()-1];
            s0 =s.name[0];
            S.add(s0,s.sum[0]);
            U.Delete(s0);
            if (S.getLen() == V){
                break;
            }
            k = s.getId(s0);
        }
        for (int l = 0; l < S.getLen(); l++) {
            System.out.print(" ("+S.name[l]+" , "+S.sum[l]+") ");
            System.out.print("\t");

        }
    }
}





 

 

 

谢谢观赏!!!!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值