Java数据结构-有向图实验,使用邻接表构建有向图

一.问题分析

算法设计
采用 邻接表 存储 有向图 ,设计算法判断任意两个顶点间是否存在路径。
提示:
1. 建立图
2. 利用深度优先遍历,寻找到一个节点
3. 基于找到的节点,查找邻接表,判断是否存在这样的路径

1.邻接表

                                    表节点

                                    顶点节点

无向图

有向图

2.图的遍历

java实现图的深度优先遍历dfs与广度优先遍历bfs

深度优先遍历

二.概要设计

最好一个类创建一个文件

1.VNode类

定义顶点节点,存放顶点的名称或相关数据,指针。

package Study;

public class VNode<T> { //顶点结点类型定义
    T data; //存储顶点的名称或其相关信息
    ArcNode firstArc; //指向顶点Vi的第一个邻接点的边结点
    public VNode() {
        data=null;firstArc=null;
    }
}

2.ArcNode类

定义边节点,存放邻接点的序号,权重,指针。

package Study;

public class ArcNode { //边结点的类型定义
    int adjVex; //存放邻接的点的序号
    ArcNode nextArc; //指向Vi下一个邻接点的边结点
    int weight;//权值
    public ArcNode(){
        adjVex=0;weight=0;nextArc=null;
    }
}

3.ALGraph类

定义图,包含顶点数组,图的顶点数,弧数和封装的函数

封装的函数
CreateLink()

创建有向图的邻接表

LocateVex()

查找顶点,找到后返回其在顶点数组中的索引号,若不存在,返回-1

hasPath()

调用LocateVex()查找需判断路径的起始点和终止点,标记每一个节点的状态(是否被访问),调用dfs()

dfs()

实现深度优(DFS),用于判断两个顶点之间是否存在路劲

DisplayAdjList()

输出有向图的邻接表

package Study;

import java.util.Scanner;

public class ALGraph<T> { //图的邻接表数据类型
    protected final int MAXSIZE=10;
    protected VNode[]  adjList; //顶点结点信息
    int n,e;//图的顶点数和弧数
    public ALGraph(){
        adjList=new VNode[MAXSIZE];
    }
    public void CreateLink(){ //创建无向图的邻接表
        int i,j,k;
        T v1,v2;
        ArcNode s;
        String str;
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入图的顶点数及边数");
        System.out.print("顶点数n="); n=sc.nextInt();;
        System.out.print("边数e=");e=sc.nextInt();
        System.out.println("请输入图的顶点信息:");
        str=sc.next();
        for(i=0;i<n;i++){
            adjList[i]=new VNode();
            adjList[i].data=str.charAt(i);//构造顶点信息
            adjList[i].firstArc=null;
        }
        System.out.println("请输入图的边的信息:");
        for(k=0;k<e;k++){
            System.out.print("请输入第"+(k+1)+"条边的两个端点:");
            str=sc.next();//输入一条边的两个顶点
            v1=(T) (Object)str.charAt(0);
            v2=(T) (Object)str.charAt(1);
            //确定两个顶点在图G中的位置
            i=LocateVex(v1);j=LocateVex(v2);
            if(i>=0&&j>=0){
                s=new ArcNode();
                s.adjVex=j;
                s.nextArc=adjList[i].firstArc;
                adjList[i].firstArc=s;
            }
        }
    }

    //在图中查找顶点v,找到后返回其在顶点数组中的索引号,若不存在,返回-1
    public int LocateVex(T v){
        int i;
        for(i=0;i<n;i++)
            if(adjList[i].data==v)return i;
        return -1;
    }

    // 判断任意两个顶点间是否存在路径
    public boolean hasPath(T v1, T v2) {
        int start = LocateVex(v1);//获取起始点在顶点数组中的索引
        int end = LocateVex(v2);//获取终止点在顶点数组中的索引
        if (start == -1 || end == -1) {
            // 顶点不存在
            return false;
        }

        boolean[] visited = new boolean[n];//创建一个布尔数组用于标记顶点的访问状态
        return dfs(start, end, visited);//调用dfs
    }

    private boolean dfs(int current, int end, boolean[] visited) {
        if (current == end) {
            return true; // 如果当前节点是目标节点,则找到路径
        }

        visited[current] = true;//标记当前节点已被访问

        ArcNode p = adjList[current].firstArc;//获取当前节点的邻接表的第一个边界点
        while (p != null) {
            //对于当前节点的每一个边节点,如果没有被访问过,且从他开始存在路径到目标终止顶点
            //则说明存在从当前顶点到目标终点的路径,返回true
            if (!visited[p.adjVex] && dfs(p.adjVex, end, visited)) {//递归调用
                return true;
            }
            p = p.nextArc;//移动到下一个邻接点
        }
        return false;//没有找到路径,返回false
    }
    public void DisplayAdjList(){ //在屏幕上显示图的邻接表表示
        int i;
        ArcNode p;
        System.out.println("图的邻接表表示:");
        for(i=0;i<n;i++){
            System.out.print("\n  "+adjList[i].data);
            p=adjList[i].firstArc;
            while(p!=null){
                System.out.print("-->"+p.adjVex);p=p.nextArc;
            }
        }
        System.out.println();
    }
}

4.测试类-Main

package Study;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        ALGraph<Character> G=new ALGraph<>();//创建对象
        G.CreateLink();//构建有向图
        G.DisplayAdjList();//输出有向图

        //键盘输入需要查找路径的开始节点与结束节点
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入开始节点:");
        char startNode = scanner.next().charAt(0);
        System.out.print("请输入结束节点:");
        char endNode = scanner.next().charAt(0);

        boolean hasPath = G.hasPath(startNode, endNode);//判断路径是否存在
        if (hasPath) {//输出结果
            System.out.println("存在路径从顶点 " + startNode + " 到顶点 " + endNode);
        } else {
            System.out.println("不存在路径从顶点 " + startNode + " 到顶点 " + endNode);
        }
    }
}

三.测试结果

  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

招摇181

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值