7创建图及图的遍历(java实现)

Posted karrya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7创建图及图的遍历(java实现)相关的知识,希望对你有一定的参考价值。

1、顺序表用于图的深度优先遍历

public class SeqList 

    public final int MaxSize = 10;

    public Object list[];
    public int size;

    /**
     * 初始化
     */
    public SeqList() 
        list = new Object[MaxSize];
        this.size = 0;
    

   /* public SeqList initSeqList(SeqList seqList) 
        seqList.list = new Object[MaxSize];
        seqList.size = 0;
    */

    public boolean isFull(SeqList list) 
        if (list.size >= MaxSize) 
            return true;
        
        return false;
    

    public boolean isEmpty(SeqList list) 
        if (list.size <= 0) 
            return true;
        
        return false;
    

    public void insertList(SeqList seqList, int i, Object data) 
        if (isFull(seqList)) 
            System.out.println("已满无法插入");
            return;
         else if (i < 0 || i > seqList.size) 
            System.out.println("您输入的位置有问题");
            return;
        

        for (int j = seqList.size; j > i; j--) 
            seqList.list[j] = seqList.list[j - 1];
        

        seqList.list[i] = data;
        seqList.size++;
    

    public void deleteList(SeqList seqList, int i) 
        if (isEmpty(seqList)) 
            System.out.println("已空,没有元素可删除");
            return;
         else if (i < 0 || i >= seqList.size) 
            System.out.println("您输入的位置参数有问题");
            return;
        

        for (int j = i+1; j <= seqList.size - 1; j++) 
            seqList.list[j-1] = seqList.list[j];
        
        seqList.size--;
    

    public int getSize(SeqList seqList) 
        return  seqList.size;
    

    public Object getData(SeqList seqList, int i) 
        if (isEmpty(seqList))
            System.out.println("已空没有可取元素");
            return null;
        else if(i<0 || i>= seqList.size)
            System.out.println("您给的位置有问题");
            return null;
        

        return seqList.list[i];
    

    public void printf(SeqList seqList) 
        if (isEmpty(seqList))
            System.out.println("已空,无需遍历");
            return;
        

        for (int i = 0; i < seqList.size; i++) 
            System.out.print(seqList.list[i] + " ");
        
    


    public static void main(String[] args) 
        SeqList seqList = new SeqList();

        System.out.println("元素个数: "+  seqList.getSize(seqList));
        seqList.printf(seqList);
        for (int i = 0; i < seqList.MaxSize; i++) 
            seqList.insertList(seqList,i,i);
        

        seqList.deleteList(seqList,0);

        seqList.insertList(seqList,0,10);
        System.out.println("元素个数: "+  seqList.getSize(seqList));
        seqList.printf(seqList);


    

2、创建顺序队列用户广度优先遍历

public class SeqQueue 

    public final int MaxSize = 8;

    public Object seqqueue[];
    public int front; // 队头
    public int rear;
    public int size;

    public SeqQueue() 
        this.size = 0;
        this.rear = 0;
        this.front = 0;
        this.seqqueue = new Object[MaxSize];
    

    public boolean isFull(SeqQueue seqQueue) 
        if (seqQueue.size > 0 && seqQueue.rear == seqQueue.front) 
            return true;
        
        return false;
    

    public boolean isEmpty(SeqQueue seqQueue) 
        if (seqQueue.size <= 0) 
            return true;
        
        return false;
    

    public void queueAppend(SeqQueue seqQueue, Object data) 
        if (isFull(seqQueue)) 
            System.out.println("已满无法插入");
            return;
        
        seqQueue.seqqueue[seqQueue.rear] = data;
        seqQueue.rear = (seqQueue.rear + 1) % MaxSize;
        seqQueue.size++;
    

    public Object queueDelete(SeqQueue seqQueue) 
        if (isEmpty(seqQueue)) 
            System.out.println("已空");
            return null;
        
        Object x = seqQueue.seqqueue[seqQueue.front];

        seqQueue.front = (seqQueue.front + 1) % MaxSize;
        seqQueue.size--;
        return x;
    

    public static void main(String[] args) 
        SeqQueue seqQueue = new SeqQueue();
        seqQueue.queueDelete(seqQueue);

        for (int i = 0; i < 9; i++) 
            seqQueue.queueAppend(seqQueue, i);
        

       for (int i = 0; i < 8; i++) 
           System.out.println( seqQueue.queueDelete(seqQueue) + " ");
           ;
        


    

3、创建需要插入的图信息类

public class CreateE 
    public int row; //行下标
    public int col; //列下标
    public  int weight; // 权重

    public CreateE() 
    

    public CreateE(int row, int col, int weight) 
        this.row = row;
        this.col = col;
        this.weight = weight;
    

4、图的实现

/**
 * 图的邻接矩阵实现
 *      —— Wij     (vi,vj)或<vi,vj>
 *      |
 * aij = —— 无穷    i != j
 *     |
 *     —— 0       i = j
 */
public class Graph 

    public final int MaxWeight = 1000; //定义为无穷大(用于存储)
    public final int MaxVertices = 10; //顶点的最大值

    SeqList vertices;  //存放顶点的顺序表
    int edge[][];      //存放边的邻接矩阵
    int numberedge;    //边的条数

    public Graph() 
        edge = new int[MaxVertices][MaxVertices]; //初始化边的最大数组(这个和顺序表差不多)
    

    /**
     * @param graph :要初始化的图
     * @param n     :给图分配几个顶点
     */
    public Graph initGraph(Graph graph, int n) 
        for (int i = 0; i < n; i++) 
            for (int j = 0; j < n; j++) 
                if (i == j) 
                    graph.edge[i][j] = 0; //对角线全为0
                 else 
                    graph.edge[i][j] = MaxWeight; //无穷大
                
            
        

        graph.numberedge = 0;  //初始边条数0
        graph.vertices = new SeqList();  //顶点顺序表初始化

        return graph;
    

    /**
     * 插入顶点
     *
     * @param graph  :需要插入顶点的图
     * @param vertex :插入的顶点值
     */
    public void insertVertex(Graph graph, Object vertex) 
        graph.vertices.insertList(graph.vertices, graph.vertices.size, vertex);
    

    /**
     * 插入边
     *
     * @param graph  : 需要插入边的图
     * @param vi     :边的一个顶点
     * @param vj     :边的另一顶点
     * @param weight :边上的权重
     */
    public void insertEdge(Graph graph, int vi, int vj, int weight) 
        if (vi < 0 || vi >= graph.vertices.size || vj < 0 || vj >= graph.vertices.size) 
            System.out.println("参数vi,vj越界");
            return;
        
        graph.edge[vi][vj] = weight;
        graph.numberedge++;
    

    /**
     * 删除边
     * @param graph : 需要处理的图
     * @param vi :顶点i
     * @param vj : 顶点j
     */
    public void deleteEdge(Graph graph,int vi,int vj) 
        if (vi < 0 || vi >= graph.vertices.size || vj < 0 || vj >= graph.vertices.size) 
            System.out.println("参数vi,vj越界");
            return;
        else if(graph.edge[vi][vj] == MaxWeight || vi == vj)
            System.out.println("边不存在");
            return;
        
        graph.edge[vi][vj] = MaxWeight;
        graph.numberedge--;
    

    /**
     * 创建图
     * @param graph :要创建的图
     * @param V :顶点
     * @param n :d顶点个数
     * @param E :边
     * @param e :边的个数
     */
    public void CreateGraph(Graph graph,Object V[],int n,CreateE E[],int e) 
        for (int i = 0; i < n; i++) 
            graph.insertVertex(graph,V[i]);
        
        for (int i = 0; i < e; i++) 
            graph.insertEdge(graph,E[i].row,E[i].col,E[i].weight);
        
    

    /**
     * 获取图的边的条数
     * @param graph : 需要操作的图
     */
    public void getNumberEdge(Graph graph) 
        if (graph == null)
            System.out.println("该图不存在");
            return;
        
        System.out.println("边的条数: " + graph.numberedge);
    

    /**
     * 取第一个邻接顶点
     * @param graph :将要操作的图
     * @param v : 某个顶点开始的第一个邻接顶点
     * @return :找到返回邻接顶点下标,找不到反回-1,错误返回-1
     */
    public int getFirstVex(Graph graph, int v) 
        if (v < 0 || v >= graph.vertices.size) 
            System.out.println("获取第一个邻接顶点参数有问题");
            return -1;
        
        for (int col = 0; col < graph.vertices.size; col++) 
            if (graph.edge[v][col] > 0 && graph.edge[v][col] < MaxWeight) //找到本顶点的二位数组中大与0小于无穷的第一个值,就是第一个邻接顶点
                return col;
            
        
        return -1;
    

    /**
     * 获取下一连接顶点
     * @param graph :需要操作的图
     * @param v1 :第一个顶点
     * @param v2 :第一个顶点的邻接顶点
     */
    public int getNextVex(Graph graph,int v1,int v2) 
        if (v1 <0 || v1 >= graph.vertices.size || v2 <0 || v2 >= graph.vertices.size)
            System.out.println("您要获取的下一邻接顶点参数有问题");
            return -1; 
        
        for (int col = v2 + 1; col < graph.vertices.size; col++) 
            if (graph.edge[v1][col] >0 && graph.edge[v1][col] < MaxWeight)
                return col;
            
        
        return  -1;
    

    /**
     * 连通图的深度优先遍历
     * @param graph 需要操作的图
     * @param v : 以某个顶点开始遍历
     * @param visited  :改点是否被访问
     */
    public void DepthSearch(Graph graph,int v,int visited[]) 
        System.out.print(graph.vertices.list[v] + " ");  //先打印第一个访问的顶点
        visited[v] = 1 ; //让改点为已经访问过 1 :访问过 0 : 未访问

        int col = graph.getFirstVex(graph,v);  //获取访问顶点的下一顶点

        while (col != -1)   //如果该节点存在
            if (visited[col] == 0)
                graph.DepthSearch(graph,col,visited);
            
            col = graph.getNextVex(graph,v,col);
        
    

    /**
     * 非连通图的深度优先遍历
     */
    public void DepthFirstSearch(Graph graph) 
        int visited[] = new int[graph.vertices.size];
        for (int i = 0; i < graph.vertices.size; i++) 
            visited[i] = 0; //未访问标记初始值为0
        
        for (int i = 0; i < graph.vertices.size; i++) 
            if (visited[i] == 0)
                graph.DepthSearch(graph,i,visited);
            
        
    

    /**
     * 连通图的广度优先遍历
     * @param graph
     * @param v
     * @param visited
     */
    public void BroadSearch(Graph graph,int v,int visited[]) 
        SeqQueue seqQueue = new SeqQueue();
        System.out.print(graph.vertices.list[v]+" ");
        visited[v] = 1;
        seqQueue.queueAppend(seqQueue,v);   //初始顶点入队
        while (!seqQueue.isEmpty(seqQueue))   //队列未空
            int n  = (int)seqQueue.queueDelete(seqQueue);
            int col = graph.getFirstVex(graph,n);
            while (col != -1)
                if (visited[col] == 0)
                    System.out.print(graph.vertices.list[col] + " ");
                    visited[col] = 1;    //设为已访问
                    seqQueue.queueAppend(seqQueue,col);   //邻接顶点入队
                
                col = graph.getNextVex(graph,n,col);
            

        
    

    public void BroadFirstSearch(Graph graph) 
        int visited[] = new int[graph.vertices.size];
        for (int i = 0; i < graph.vertices.size; i++) 
            visited[i] = 0; //访问标记初始为0
        
        for (int i = 0; i < graph.vertices.size; i++) 
            if (visited[i] == 0)
                BroadSearch(graph,i,visited);
            
        
    

    public static void main(String[] args) 
        Graph graph = new Graph();
        int n = 6,e=6;
        graph.initGraph(graph,n);

        Object V[] = ‘A‘,‘B‘,‘C‘,‘D‘,‘E‘,‘F‘;

        CreateE E[] = new CreateE(0,1,10),new CreateE(0,4,20),new CreateE(1,3,30),new CreateE(2,1,40),new CreateE(3,2,50),new CreateE(0,5,30);

        graph.CreateGraph(graph,V,n,E,e);

        System.out.print("顶点集合:");
        for (int i = 0; i < graph.vertices.size; i++) 
            System.out.print(graph.vertices.list[i]+ " ");
        
        System.out.println();
        
        System.out.println("权值集合");
        for (int i = 0; i < graph.vertices.size; i++) 
            for (int j = 0; j < graph.vertices.size; j++) 
                System.out.print(graph.edge[i][j]+"\t\t");
            
            System.out.println();
        
        graph.getNumberEdge(graph);
        
        System.out.println("取第一个邻接顶点 : " + graph.vertices.list[graph.getFirstVex(graph,0)]); //这里取不到就会报错哦。因为取不到,我这设置返回-1
        System.out.println("取下一个邻接顶点 : " +graph.vertices.list[graph.getNextVex(graph,0,graph.getFirstVex(graph,0))]);


        
        System.out.print("图的深度优先遍历 :");

        graph.DepthFirstSearch(graph);
        System.out.println();

        System.out.print("图的广度优先遍历 :");

        graph.BroadFirstSearch(graph);
        System.out.println();
        graph.deleteEdge(graph,0,1);
        graph.getNumberEdge(graph);
        System.out.println("权值集合");
        for (int i = 0; i < graph.vertices.size; i++) 
            for (int j = 0; j < graph.vertices.size; j++) 
                System.out.print(graph.edge[i][j]+"\t\t");
            
            System.out.println();
        

    


5、实现结果

顶点集合:A B C D E F 
权值集合
0        10        1000        1000        20        30        
1000        0        1000        30        1000        1000        
1000        40        0        1000        1000        1000        
1000        1000        50        0        1000        1000        
1000        1000        1000        1000        0        1000        
1000        1000        1000        1000        1000        0        
边的条数: 6
取第一个邻接顶点 : B
取下一个邻接顶点 : E
图的深度优先遍历 :A B D C E F 
图的广度优先遍历 :A B E F D C 
边的条数: 5
权值集合
0        1000        1000        1000        20        30        
1000        0        1000        30        1000        1000        
1000        40        0        1000        1000        1000        
1000        1000        50        0        1000        1000        
1000        1000        1000        1000        0        1000        
1000        1000        1000        1000        1000        0    

 

以上是关于7创建图及图的遍历(java实现)的主要内容,如果未能解决你的问题,请参考以下文章

算法笔记图结构及图的 DFS 和 BFS 介绍

定义Arraylist集合,存储1-20,遍历集合,把奇数偶数分别放在两个集合,遍历这两个集合

Java实现无向图的邻接列表表示,深度遍历及广度遍历

JS实现图的创建和遍历

Java实现图的深度和广度优先遍历算法

图的遍历和生成树求解实现 (c语言版)