• 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]+"		");
                }
                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]+"		");
                }
                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    
  • 相关阅读:
    thinkphp中field的用法
    Thinkphp常用标签
    thinkphp框架的相关总结
    TP 控制器扩展_initialize方法实现原理
    Thinkphp中的volist标签(查询数据集(select方法)的结果输出)用法简介
    php中遍历数组的方法
    django自定义过滤器
    centos7 安装 mysql
    centos7 安装 nginx
    centos 服务器改名
  • 原文地址:https://www.cnblogs.com/karrya/p/11225832.html
Copyright © 2020-2023  润新知