zoukankan      html  css  js  c++  java
  • 20162328蔡文琛 实验四 图的实现与应用

    20162328蔡文琛 大二 实验四

    任务详情

    实验1

    用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器

    实现类
    public class MatrixUDG {
    
        private char[] mVexs;       // 顶点集合
        private int[][] mMatrix;    // 邻接矩阵
    
        /*
         * 创建图(自己输入数据)
         */
        public boolean isEmpty(){
            boolean result = true;
            if (mVexs.equals(0) )
                return result = false;
            return result;
        }
        public void size(){
            int num= 0;
            num = mVexs.length;
            System.out.println(num);
        }
        public MatrixUDG(char[] vexs, char[][] edges) {
    
            // 初始化"顶点数"和"边数"
            int vlen = vexs.length;
            int elen = edges.length;
    
            // 初始化"顶点"
            mVexs = new char[vlen];
            for (int i = 0; i < mVexs.length; i++)
                mVexs[i] = vexs[i];
    
            // 初始化"边"
            mMatrix = new int[vlen][vlen];
            for (int i = 0; i < elen; i++) {
                // 读取边的起始顶点和结束顶点
                int p1 = getPosition(edges[i][0]);
                int p2 = getPosition(edges[i][1]);
    
                mMatrix[p1][p2] = 1;
                mMatrix[p2][p1] = 1;
            }
        }
    
        /*
         * 返回ch位置
         */
        private int getPosition(char ch) {
            for (int i = 0; i < mVexs.length; i++)
                if (mVexs[i] == ch)
                    return i;
            return -1;
        }
    
        /*
         * 读取一个输入字符
         */
        private char readChar() {
            char ch = '0';
    
            do {
                try {
                    ch = (char) System.in.read();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
    
            return ch;
        }
    
        /*
         * 读取一个输入字符
         */
        private int readInt() {
            Scanner scanner = new Scanner(System.in);
            return scanner.nextInt();
        }
    
        /*
         * 打印矩阵队列图
         */
        public void print() {
            System.out.printf("Martix Graph:
    ");
            for (int i = 0; i < mVexs.length; i++) {
                for (int j = 0; j < mVexs.length; j++)
                    System.out.printf("%d ", mMatrix[i][j]);
                System.out.printf("
    ");
            }
        }
    }
    
    

    实验2

    用十字链表实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器

    public class Main {
        public static class Vertex<E,T>  {
            E data;
            Edge<T> firstIn;
            Edge<T> firstOut;
    
            public Vertex(E data) {
                this.data = data;
            }
        }
        public static class Edge<E> {
            E data;
            int fromVertexIndex;
            int toVertexIndex;
            Edge<E> nextSameFromVertex;
            Edge<E> nextSameToVertex;
    
            public Edge(E data, int fromVertexIndex, int toVertexIndex) {
                this.data = data;
                this.fromVertexIndex = fromVertexIndex;
                this.toVertexIndex = toVertexIndex;
            }
        }
        public static void insertEdge(Edge<Integer> edge, List<Vertex<Integer, Integer>> vertexList) {
            int fromVertexIndex = edge.fromVertexIndex;
            int toVertexIndex = edge.toVertexIndex;
            Vertex<Integer, Integer> fromVertex = vertexList.get(fromVertexIndex);
            Vertex<Integer, Integer> toVertex = vertexList.get(toVertexIndex);
    
            if (fromVertex.firstOut == null) {
                //插入到顶点的出边属性
                fromVertex.firstOut = edge;
            } else {
                // 插入到edge的nextSameFromVertex属性
                Edge<Integer> tempEdge = fromVertex.firstOut;
                //找到最后一个Edge
                while (tempEdge.nextSameFromVertex != null) {
                    tempEdge = tempEdge.nextSameFromVertex;
                }
                tempEdge.nextSameFromVertex = edge;
            }
            if (toVertex.firstIn == null) {
                //插入到顶点的入边属性
                toVertex.firstIn = edge;
            } else {
                // 插入到edge的nextSameToVertex属性
                Edge<Integer> tempEdge = toVertex.firstIn;
                //找到最后一个Edge
                while (tempEdge.nextSameToVertex != null) {
                    tempEdge = tempEdge.nextSameToVertex;
                }
                tempEdge.nextSameToVertex = edge;
            }
        }
        public static void printVertexAndEdges(List<Vertex<Integer, Integer>> list) {
            for (Vertex<Integer, Integer> vertex : list) {
                //输出入度
                String infoIn = String.format("vertex: %3d - its in-edge are: ", vertex.data);
                Edge<Integer> edge = vertex.firstIn;
                while (edge != null) {
                    infoIn += String.format("(from: %d, to: %d, data: %d)", edge.fromVertexIndex, edge.toVertexIndex, edge.data);
                    edge = edge.nextSameToVertex;
                }
                System.out.println(infoIn);
                //输出出度
                String infoOut = String.format("vertex: %3d - its out-edge are: ", vertex.data);
                Edge<Integer> edgeOut = vertex.firstOut;
                while (edgeOut != null) {
                    infoOut += String.format("(from: %d, to: %d, data: %d)", edgeOut.fromVertexIndex, edgeOut.toVertexIndex, edgeOut.data);
                    edgeOut = edgeOut.nextSameFromVertex;
                }
                System.out.println(infoOut);
            }
        }
        public static void main(String[] args) {
            int vertexNumber = 12;
            int edgeNumber = 21;
            // 检查边的数量是否正确
            // 有向完全图
            int maxEdgeNumber = vertexNumber*(vertexNumber-1);
            if (edgeNumber < 0 || edgeNumber > maxEdgeNumber) {
                return;
            }
            // 输入有向图数据
            // 1. 先输入顶点,暂时令firstIn, firstOut为null;
            ArrayList<Vertex<Integer, Integer>> vertexList = new ArrayList<>();
            for (int i=0; i<vertexNumber; i++) {
                Vertex<Integer, Integer> v = new Vertex<>(i);
                vertexList.add(v);
            }
    

    实验3

    实现PP19.9

    public class Router {
            public int id;
             public List<Table> tableList;
    
            public Router(){
            tableList=new ArrayList<Table>();
            }
            public void printTable(){
            System.out.println("------------routTable of No "+id+"router is------------------");
            for (Table table : tableList) {
            System.out.println(table.hostId+" "+table.netId+"  "+table.distance+"  "+table.nextJumpId);
            }
           }
            public boolean isNearby(Router router){
             List<Table> tablesOther= router.tableList;
            for (Table table : tablesOther) {
           for (Table table2 : tableList) {
            if ((table.netId==table2.netId)&&(table.distance==1)&&(table2.distance==1)&&(table.hostId!=table2.hostId)) {
            return true;//判断相邻的条件:两个路由器,对于相同的网络,都直接相连(距离为1)  
            }
            }
            }
            return false;
            }
            public void init(int[][]near){//初始化问题:输入邻接矩阵,对每一个路由器,循环感知相连的网络  
            tableList=new ArrayList<Table>();
            for (int i=0;i< near[id].length;i++)//对矩阵的第id行做循环,注意net编号是从0开始的  
            {
            if (near[id][i]==1) {//id路由器和i号网络相连  
             Table temptTable=new Table();
            temptTable.hostId=id;
            temptTable.netId=i;
            temptTable.distance=1;
            temptTable.nextJumpId=-1;//下一跳id为-1,表示直接交付  
            tableList.add(temptTable);
            }
            }
            }
            public void send(Router router){//向指定路由器发送table,假设已知道二者相连  
           router.update(tableList);//直接让对方更新自己的表就行了  
            }
            public void update(List <Table> newList){
            java.util.Iterator<Table > iterator1= newList.iterator();
            while(iterator1.hasNext()) {//对于对方每一项,检查自己所有项  
            Table table1= iterator1.next();//取出对方项  
            List<Table>tempTableList=new ArrayList<Table>();//临时表,存储新增的项目  
           int flag=0;//标志变量,记录是否找到相同目的地址的项  
            java.util.Iterator<Table> iterator2=tableList.iterator();
          while (iterator2.hasNext()) {
            Table table2 = (Table) iterator2.next();//  
           if (table2.netId==table1.netId) {
            flag=1;
      if (table2.nextJumpId==table1.hostId) {
          table2.distance=table1.distance+1;
     }
    else {
    if (table2.distance>table1.distance+1) {
    table2.nextJumpId=table1.hostId;
    table2.distance=table1.distance+1;
    }
    }
    }
    }
    if (flag==0){
    flag=1;
         Table tempTable=new Table();
         tempTable.hostId=id;
      tempTable.netId=table1.netId;
       tempTable.nextJumpId=table1.hostId;
    tempTable.distance=table1.distance+1;
    
    tableList.add(tempTable);
    }
    
    }
    printTable();
    }
            }
    

    遍历类

    public class Graph {
        private boolean[] flag;
    
            static String[] vertexs;
    
             int[][] edges;
    
    
            public void DFSTraverse(int num1) {
            flag = new boolean[num1];
            for (int i = 0; i < num1; i++) {
           if (flag[i] == false) {// 当前顶点没有被访问
            DFS(i);
            }
            }
            }
    
    
           public void DFS(int i) {
            flag[i] = true;// 第i个顶点被访问
            System.out.print(vertexs[i] + " ");
         for (int j = 0; j < flag.length; j++) {
            if (flag[j] == false && edges[i][j] == 1) {
            DFS(j);
            }
            }
            }
    
    
           public ArrayList<String> BFSTraverse(int[][] ints, String[] m, int num) {
            flag = new boolean[num];
            ArrayList<String> result = new ArrayList<>();
            LinkedList<Integer> queue = new LinkedList<Integer>();
            flag[0] = true;
            queue.add(0);
            while (!queue.isEmpty()) {
            int j = queue.remove(0);
            result.add(m[j]);
            for (int k = 0; k < num; k++) {
            if (ints[j][k] == 1 && flag[k] == false) {
            flag[k] = true;
            queue.add(k);
            }
            }
            }
            return result;
            }
    
    

    代码参考http://blog.csdn.net/coslay/article/details/47748089
    http://www.sharejs.com/codes/java/6692
    http://blog.csdn.net/caib1109/article/details/72777806

  • 相关阅读:
    SpringMVC请求参数接收总结(一)
    不用 Spring Security 可否?试试这个小而美的安全框架
    @ConfigurationProperties 注解使用姿势,这一篇就够了
    Spring Aware 到底是什么?
    git rebase VS git merge? 更优雅的 git 合并方式值得拥有
    Spring Bean 生命周期之destroy——终极信仰
    面试还不知道BeanFactory和ApplicationContext的区别?
    Java设计模式学习记录-享元模式
    Java设计模式学习记录-外观模式
    Java设计模式学习记录-装饰模式
  • 原文地址:https://www.cnblogs.com/Cai77/p/7899621.html
Copyright © 2011-2022 走看看