20182323 2019-2020-1 《数据结构与面向对象程序设计》第8周学习总结

Posted caoqian1314

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20182323 2019-2020-1 《数据结构与面向对象程序设计》第8周学习总结相关的知识,希望对你有一定的参考价值。

目录

学号20182323 2019-2020-1 《数据结构与面向对象程序设计》第8周学习总结

教材学习内容总结

第13章

查找与排序

查找

  1. 线性查找:属于无序查找算法。从序列一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。
ps:设置哨兵可提高查找效率(设第一个为哨兵,用n记录当前位置,遍历整个序列后弹出的条件为“n==0”)
  1. 二分法查找
  • 说明:元素必须是有序的,如果是无序的则要先进行排序操作。
  • 基本思想:用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。

查找总结:
技术图片

排序

  1. 插入排序:

    将待插元素,依次与已排序好的子数列元素从后到前进行比较,如果当前元素值比待插元素值大,则将移位到与其相邻的后一个位置,否则直接将待插元素插入当前元素相邻的后一位置,因为说明已经找到插入点的最终位置
    技术图片

  2. 快速排序:

    选择待排数列的首部第一个元素为基准元素,设置两指针,分别指向数列首尾部位置,假设两指针分别设为i和j。每次遍历的过程是这样的,首先遍历指针j所指向的元素,直到j指向的元素值小于基准元素时,停止遍历,将其与指针i所指向的元素进行交换,因为当前指针所指位置就是用于插入较基准元素小的元素,然后再将指针i加一。接着轮到指针i遍历,直到i所指向的元素值大于基准元素时,停止遍历,将其与指针j所指向的元素进行交换,之所以可以交换,是因为指针j所指向的元素刚刚已经交换到前半部分呢,故可以直接选择覆盖就行,这样就将大于基准元素的元素放于后半部分。依此类推,直到指针i与指针相等或者大于时,停止外部循环。最后直接将基准元素直接放置于指针i所指向的位置即可,完成分区操作。

    接下来,我们通过示图来展示上述分区算法思路的过程:
    技术图片

  3. 归并排序:

    简单的说把一串数,从中平等分为两份,再把两份再细分,直到不能细分为止,这就是分而治之的分的步骤. 再从最小的单元,两两合并,合并的规则是将其按从小到大的顺序放到一个临时数组中,再把这个临时数组替换原数组相应位置,这就是治. 图解如下:
    技术图片

技术图片

排序总结:
技术图片

教材学习中的问题和解决过程

  • 问题1:如何用代码实现归并排序

  • 问题1解决方案:

public static void mergeSort(int[] a,int s,int e){
    int m = (s + e) / 2;
    if (s < e){
      mergeSort(a,s,m);
      mergeSort(a,m+1,e);
      //归并
      merge(a,s,m,e);
    }
  }

  private static void merge(int[] a, int s, int m, int e) {
    //初始化一个从起始s到终止e的一个数组
    int[] temp = new int[(e - s) + 1];
    //左起始指针
    int l = s;
    //右起始指针
    int r = m+1;
    int i = 0;
    //将s-e这段数据在逻辑上一分为二,l-m为一个左边的数组,r-e为一个右边的数组,两边都是有序的
    //从两边的第一个指针开始遍历,将其中小的那个值放在temp数组中
    while (l <= m && r <= e){
      if (a[l] < a[r]){
        temp[i++] = a[l++];
      }else{
        temp[i++] = a[r++];
      }
    }

    //将两个数组剩余的数放到temp中
    while (l <= m){
      temp[i++] = a[l++];
    }
    while (r <= e){
      temp[i++] = a[r++];
    }
    
    //将temp数组覆盖原数组
    for (int n = 0; n < temp.length; n++) {
      a[s+n] = temp[n];
    }
    
  }

代码调试中的问题和解决过程

  • 问题1:

  • 出现的第一个错误是拉下了第21行的外层循环,导致指针在进行移动的时候没有在正确的位置停下来。
  • 第二个错误是第32行的arr[right]=arr[left]; 我写成了arr[lefr]=pivotkey;而丢掉了第三十六行的语句。而这个错误导致了栈溢出,“Exception in thread "main" java.lang.StackOverflowError”,
  • 第三个错误是第22行的while(left<right&&arr[right]>=pivotkey)中的判断条件我落下了“=”写成了while(left<right&&arr[right]>pivotkey)
  • 这样就会导致一个问题,当数组中出现两个相等的数时,因为判断条件中没有相等这一条,所以就不会执行while里面的语句,造成程序一直不能跳过这两个相等的数,也就是说当数组中有两个相等的元素时,程序就会执行到这里卡。

  • 解决过程:


//快速排序算法

class QuickSort{

    //主方法

    public void quicksort(int arr[],int left,int right) {

        int  pivot;

        if(left<right){

            //以pivot为枢轴,较之小的元素在左,较之大的元素在右

            pivot=partition(arr, left, right);

            //对左边的元素调用快速排序

            quicksort(arr,left,pivot-1);

            //对右边数组调用快速排序

            quicksort(arr,pivot+1,right);

        }

        

    }

    

    //快速排序算法的切割链表

    public int partition(int arr[],int left,int right){

        int pivotkey = arr[left];

        //枢轴选中后永远不变,最终在中间,前边小后变大

        while(left<right) {

            while(left<right&&arr[right]>=pivotkey)

            {

                --right;

            }

            arr[left]=arr[right];

            //此时arr[left]为空,不过它的值保存着pivot中

            while(left<right&&arr[left]<=pivotkey)

            {

                ++left;

            }

            arr[right]=arr[left];

            

            

        }

    arr[left]=pivotkey;

    return left;

    }

}

代码托管

技术图片

结对及互评

点评模板:

  • 博客中值得学习的或问题:
    • 随着学习内容难度增加,问题分析更加深刻
    • 不断查阅资料,努力解决出现的问题
  • 代码中值得学习的或问题:
    • 代码的逻辑性有待提高
    • 代码中适当加入注释会更好
  • 基于评分标准,我给本博客打分:12分。得分情况如下:
  1. 正确使用Markdown语法(加1分):
    • 不使用Markdown不加分
    • 有语法错误的不加分(链接打不开,表格不对,列表不正确...)
    • 排版混乱的不加分
  2. 模板中的要素齐全(加1分)
    • 缺少“教材学习中的问题和解决过程”的不加分
    • 缺少“代码调试中的问题和解决过程”的不加分
    • 代码托管不能打开的不加分
    • 缺少“结对及互评”的不能打开的不加分
    • 缺少“上周考试错题总结”的不能加分
    • 缺少“进度条”的不能加分
    • 缺少“参考资料”的不能加分
  3. 教材学习中的问题和解决过程(2分)

  4. 代码调试中的问题和解决过程(2分)

  5. 本周有效代码超过300分行的(加0分)

  6. 其他加分:
    • 周五前发博客的加1分
    • 感想,体会不假大空的加1分
    • 进度条中记录学习时间与改进情况的加1分
    • 有动手写新代码的加1分
    • 错题学习深入的加1分
    • 点评认真,能指出博客和代码中的问题的加1分
    • 结对学习情况真实可信的加1分

点评过的同学博客和代码

  • 本周结对学习情况
    • 结对同学学号20182315
    • 结对照片
    • 结对学习内容
      • 查找与排序

        其他(感悟、思考等,可选)

        继续潜心学习,只问初心,无问西东。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 10000行 30篇 400小时
第一周 77/77 2/2 15/15
第三周 424/501 3/5 30/30
第四周 393/894 2/7 30/30
第五周 320/1214 1/8 30/30
第六周 904/2118 2/10 30/30
第7周 1350/3468 3/13 30/30
第8周 342/3810 1/14 30/30
  • 计划学习时间:25小时

  • 实际学习时间:20小时

  • 改进情况:

参考资料

以上是关于20182323 2019-2020-1 《数据结构与面向对象程序设计》第8周学习总结的主要内容,如果未能解决你的问题,请参考以下文章

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

20182323 2019-2020-1 《数据结构与面向对象程序设计》第23周学习总结

20182323 2019-2020-1 《数据结构与面向对象程序设计》第8周学习总结

20182323 2019-2020-1 《数据结构与面向对象程序设计》第4周学习总结

20182323 哈夫曼编码测试

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