zoukankan      html  css  js  c++  java
  • 20182330 2019-2020-1 《数据结构与面向对象程序设计》实验九报告

    20182330 2019-2020-1 《数据结构与面向对象程序设计》实验九报告

    课程:《程序设计与数据结构》
    班级: 1823
    姓名: 魏冰妍
    学号:20182330
    实验教师:王志强
    实验日期:2019年12月2日
    必修/选修: 必修

    1.实验内容

    完成图的综合实践
    (1)初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)
    (2)图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)
    (3)完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环
    (4)完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出
    (5)完成有向图的单源最短路径求解(迪杰斯特拉算法)

    2. 实验过程及结果

    1.初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)

     public Sorting(char[] dingdian, EData[] bian) {
    
            int lenv = dingdian.length;
            int elen = bian.length;
    
            // 初始化顶点
            mV= new N[lenv];
            for (int i = 0; i < mV.length; i++) {
                mV[i] = new N();
                mV[i].dingdian = dingdian[i];
                mV[i].firstX = null;
            }
    
            // 初始化边
            Enum = elen;
            for (int i = 0; i < elen; i++) {
                // 读取顶点
                char c1 = bian[i].start;
                char c2 = bian[i].end;
                int weight = bian[i].weight;
                int p1 = gPs(c1);
                int p2 = gPs(c2);
                B  node1 = new B ();
                node1.i = p2;
                node1.w = weight;
                //连接
                if(mV[p1].firstX == null)
                    mV[p1].firstX = node1;
                else
                    Connect(mV[p1].firstX, node1);
                B  node2 = new B ();
                node2.i = p1;
                node2.w = weight;
                //连接
                if(mV[p2].firstX == null)
                    mV[p2].firstX = node2;
                else
                    Connect(mV[p2].firstX, node2);
            }
        }
    

    2.图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)

    • 深度优先遍历
    private void DFS(int i, boolean[] BL) {
            B node;
    
            BL[i] = true;
            System.out.printf("%c ", mV[i].dingdian);
            node = mV[i].firstX;
            while (node != null) {
                if (!BL[node.i])
                    DFS(node.i, BL);
                node = node.nextX;
            }
        }
    
    • 广度优先遍历
     public void BFS() {
            int head = 0;
            int rear = 0;
            int[] queue = new int[mV.length];            // 辅组队列
            boolean[] BL = new boolean[mV.length];  // 顶点访问标记
            for (int i = 0; i < mV.length; i++)
                BL[i] = false;
    
            System.out.printf("广度优先遍历: ");
            for (int i = 0; i < mV.length; i++) {
                if (!BL[i]) {
                    BL[i] = true;
                    System.out.printf("%c ", mV[i].dingdian);
                    queue[rear++] = i;  // 入队列
                }
    
                while (head != rear) {
                    int j = queue[head++];  // 出队列
                    B node = mV[j].firstX;
                    while (node != null) {
                        int k = node.i;
                        if (!BL[k])
                        {
                            BL[k] = true;
                            System.out.printf("%c ", mV[k].dingdian);
                            queue[rear++] = k;
                        }
                        node = node.nextX;
                    }
                }
            }
            System.out.printf("
    ");
        }
    

    3.完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环

     public int TpSort() {
            int index = 0;
            int num = mV.length;
            int[] ins;               // 入度数组
            char[] tops;
            Queue<Integer> queue;
    
            ins   = new int[num];
            tops  = new char[num];
            queue = new LinkedList<Integer>();
    
            // 统计每个顶点的入度数
            for(int i = 0; i < num; i++) {
    
                B  node = mV[i].firstX;
                while (node != null) {
                    ins[node.i]++;
                    node = node.nextX;
                }
            }
    
            // 将所有入度为0的顶点入队列
            for(int i = 0; i < num; i ++)
                if(ins[i] == 0)
                    queue.offer(i);                 // 入队列
    
            while (!queue.isEmpty()) {              // 队列非空
                int j = queue.poll().intValue();    // 出队列。j是顶点的序号
                tops[index++] = mV[j].dingdian;
                B  node = mV[j].firstX;
                while(node != null) {
                    // 入度减1。
                    ins[node.i]--;
                    // 若入度为0,则入队列
                    if( ins[node.i] == 0)
                        queue.offer(node.i);    // 入队列
    
                    node = node.nextX;
                }
            }
            if(index != num) {
                System.out.printf("有向有环图
    ");
                return 1;
            }
            // 打印拓扑排序结果
            System.out.printf("拓扑排序: ");
            for(int i = 0; i < num; i ++)
                System.out.printf("%c ", tops[i]);
            System.out.printf("
    ");
    
            return 0;
        }
    
    1. 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出
    • Kruscal算法
    public void kruskal() {
            int index = 0;                   
            int[] v = new int[Enum];     // 保存终点。
            EData[] rets = new EData[Enum];  // 暂存结果数组
            EData[] e;                      // 对应的所有边
            
            e = getEdges();
            // 将边按权排序
            sortEdges(e, Enum);
    
            for (int i=0; i<Enum; i++) {
                int p1 = gPs(e[i].start);    
                int p2 = gPs(e[i].end);       
    
                int m = getEnd(v, p1);                
                int n = getEnd(v, p2);                
                // 如果m!=n,则没有形成环路
                if (m != n) {
                    v[m] = n;                       
                    rets[index++] = e[i];          
                }
            }
    }
    

    5.完成有向图的单源最短路径求解(迪杰斯特拉算法)

    public void dijkstra(int s, int[] q, int[] t) {
            // flag[i]=true表示最短路径已成功获取。
            boolean[] flag = new boolean[mV.length];
    
            // 初始化
            for (int i = 0; i < mV.length; i++) {
                flag[i] = false;            
                q[i] = 0;                // 顶点i的前驱顶点为0。
                t[i] = getWeight(s, i);
            }
    
            // 初始化
            flag[s] = true;
            t[s] = 0;
    
       
            int k = 0;
            for (int i = 1; i < mV.length; i++) {
                // 寻找当前最小的路径;
                // 寻找当前最小的路径;
                // 寻找当前最小的路径;
                int min = INF;
                for (int j = 0; j < mV.length; j++) {
                    if (flag[j]==false && t[j]<min) {
                        min = t[j];
                        k = j;
                    }
                }
                // 获取到最短路径
                flag[k] = true;
                for (int j = 0; j < mV.length; j++) {
                    int tmp = getWeight(k, j);
                    tmp = (tmp==INF ? INF : (min + tmp)); // 防止溢出
                    if (flag[j]==false && (tmp<t[j]) )
                    {
                        t[j] = tmp;
                        q[j] = k;
                    }
                }
            }
    
    • 实验结果截图

    3. 实验过程中遇到的问题和解决过程

    • 问题1:try异常导致程序锁死。

    • 问题1解决方案:解决时发现不止我一个人有这个问题。参照博客发现是e.printStackTrace()。于是删掉 e.printStackTrace() ,异常处理。

    短时间内大量请求访问此接口 -> 代码本身有问题,很多情况下抛异常 -> e.printStackTrace() 来打印异常到控制台 -> 产生错误堆栈字符串到字符串池内存空间 -> 此内存空间一下子被占满了 -> 开始在此内存空间产出字符串的线程还没完全生产完整,就没空间了 -> 大量线程产出字符串产出到一半,等在这儿(等有内存了继续搞啊)-> 相互等待,等内存,锁死了,整个应用挂掉了。

    其他(感悟、思考等)

    最后一个小实验,个人认为图的理解比树简单一点,并且可以利用到离散中学过的知识。java结课意味着接下来可以安心复习期末和准备app了。

    参考资料

  • 相关阅读:
    Scanner扫描器
    数据类型的转换
    万年历java
    冒泡排序、选择排序(升序排序,降序排序)
    数组
    字符串大小写转换(全转)(大小写互转)
    数据库两表联查、多表联查,多重联查
    js监测输入框字数(一个汉字等于两个字母),超出限制输入无效
    几条经验让jQuery用的更漂亮
    JS实现URL的拼接转换
  • 原文地址:https://www.cnblogs.com/weiii/p/12002610.html
Copyright © 2011-2022 走看看