20162330 第六周 蓝墨云班课 队列加分项

作业要求

  • 1 用循环队列实现
    2 参考PPT用循环队列打印杨辉三角
    3 用JDB或IDEA单步跟踪排队情况,画出队列变化图,包含自己的学号信息
    4 把代码推送到代码托管平台
    5 把完成过程写一篇博客:重点是单步跟踪过程和遇到的问题及解决过程
    6 提交博客链接

设计思路

  • 杨辉三角的特点:
    ① 第 i 行有 i 个元素;
    ② 每一行的第一个元素和最后一个元素都为1;
    ③ 除了1之外,每个元素的值,都等于上一行同位置的元素以及前一个元素的和。

  • 考虑到这些特点,我们可以使用“坐标”的方式,即使用二维数组实现,但是这种方法占用的空间较大,并且计算次数较多;

  • 使用循环队列实现可以节省一定空间,如果要求计算并输出杨辉三角前 n 行的值,则队列的最大空间应为 n+2。


代码实现

  • 二维数组实现:
public class YHTriangleArray {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入杨辉三角的行数:");
        int a = scan.nextInt();

        //定义二维数组存放杨辉三角
        int arr[][] = new int[a][a];

        //行数
        for (int i = 0; i < a; i++) {
            //列数
            for (int j = 0; j <= i; j++) {
                //每行的第一列和最后一列为1
                if (j == 0 || j == i)
                    arr[i][j] = 1;

                //其余列等于前一行的相同列 + 前一行的相同列-1;
                if (i > 0 && j > 0 && j < i)
                    arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
            }
        }
        traversal(arr);
    }

    //遍历二维数组
    public static void traversal(int arr[][]) {
        System.out.println("杨辉三角如下:");
        //二维数组的行
        for (int i = 0; i < arr.length; i++) {
            //二维数组的列
            for (int j = 0; j <= i; j++) {
                int k = arr.length - i - 1;
                //居中排列
                if (j == 0) {
                    for (int a = 0; a < k; a++)
                        System.out.print(" ");
                }
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }
}
  • 循环队列实现:
public class YHTriangleQueue {
    public static void main(String args[]) {
        Scanner scan = new Scanner(System.in);
        System.out.print("请输入杨辉三角的行数:");
        int n = scan.nextInt();
        int i = 0;

        CircularArrayQueue<Integer> queue = new CircularArrayQueue<>();
        //初始值设置为 0,1
        queue.enqueue(0);
        queue.enqueue(1);

        while (i <= n) {
            int x = queue.dequeue();
            int y = queue.first();
            if (x == 0) {
                i++;  //每次 x = 0 时行数加一
                queue.enqueue(0);
            }
            queue.enqueue(x + y);  //上一轮输出值与检测值之和,相当于前一行相邻的两元素之和
            if (x == 0) {
                System.out.println();  //删除 0 相当于换行
                for (int j = 0; j < 2 * (n - i); j++) {  //根据具体变化动态输出空字符串
                    System.out.print(" ");
                }
            } else
                System.out.print(x + "   ");  //根据具体变化动态输出空字符串
        }
    }
}

运行结果及单步跟踪过程

  • 二维数组实现:

    运行结果:(左对齐)

    运行结果:(居中)

    单步跟踪过程:(以第三行输出 1 2 1 为例,分别记录赋值的3次)(点击图片可放大)


  • 循环队列实现:

    运行结果:(居中)

    单步跟踪过程:(以第二行输出 1 1 为例,分别记录输出过程中的3次)(点击图片可放大)


简易变化图

  • 二维数组实现:

  • 循环队列实现:

    【注】输出 (x,y,z) 表示输出第 x 行中第 y 个非空的元素值 z .


遇到的问题及解决方案

  • 【问题】在输出了左对齐的杨辉三角之后,我想打印居中的杨辉三角,为什么打印的杨辉三角出现了一些格式错误问题?

  • 【解决方案】使用debug单步跟踪,并一次次地修改代码。这里只举一例:

    从这次的输出结果中,可以看出从第二行开始,空字符串的输出位置就出现了问题,我发现是因为在此循环中缺少条件判断而导致每行元素之间与每行第一个非空字符串与其边缘的初始间距相同,所以第二行元素间的间距很大,到第五行时就已经小到元素之间只相距一个空字符串了,所以在这里只需要添加一个条件判断语句即可,添加后运行成功截图如下:

posted @ 2017-10-23 00:00  N-Liu  阅读(302)  评论(1编辑  收藏  举报