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

教材学习内容总结

查找

  • 高效的查找:比较次数越少。
  • 数组是Compareable对象,因此要实现Comparable接口,而且互相之间必须是可以比较的。
  • Comparable好处:可以比较多种类型的变量,但必须是可以比较的
  • 线性查找(比较简单就不贴代码了)
  • 二分查找
  • 前提:有序!!
  • 递归方法:
public  boolean Search( int[] data,int min, int max, int target)
  {
    boolean found = false;
    int midpoint = (min + max) / 2;
    if (data[midpoint]==target)
        found = true;
    else if (data[midpoint]>target)
    {
        if (min <= midpoint - 1)
            found = Search(data, min, midpoint - 1, target);
    }
    else if (midpoint + 1 <= max)
        found = Search(data,midpoint + 1, max, target);
    return found;
   }
  • 普通方法:
public boolean search(int ele){
    int temp=ele;
    int low=0;
    int high=num.length-1;
    int mid=(high+low)/2;
    while(low<=high){
        if(num[mid]==temp){
            return true;
        }
        else if(temp>num[mid]){
            low=mid+1;
        }
        else{
            high=mid-1;
        }
        mid=(high+low)/2;
    }
    return false;
}

排序

  • 简单选择排序(Selection sort)
  • 我的理解:首先在未排序序列中找到最小(大)元素,存放到序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到未排好序的序列的起始位置。以此类推,直到所有元素均排序完毕。、
  • 特点:相较于冒泡排序,交换次数少,但比较次数多,并且不稳定。
  • 复杂度分析
    平均时间复杂度:O(n²)
  • 代码实现
public static void sort(int[] a) {
    for (int i = 0; i < a.length; i++) {
        int min = i;
        for (int j = i + 1; j < a.length; j++) {
            if (a[j] < a[min]) {
                min = j;
            }
        }
        if (min != i) {
            int temp = a[i];
            a[i] = a[min];
            a[min] = temp;
        }
    }
}
  • 插入排序
  • 利用插入法对无序数组排序时,我们其实是将数组划分成两个子区间:已排好序的有序区和当前未排序的部分。插入排序的基本操作是将当前无序区的第1个元素插人到有序区中适当的位置上,使有序区变为新的有序区。
  • 我的理解:这个方法感觉跟打扑克时整理手上的牌非常类似。摸来的第1张牌不需要整理,此后每次从牌堆里(无序区)中摸最上面的1张并插入左手的牌(有序区)中正确的位置上。为了找到这个正确的位置,要将摸来的牌与左手中已有的牌逐一比较。
  • 冒泡排序
  • 很常用的一种排序,这也是我接触的第一个排序算法。
  • 我的理解:它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,直到没有再需要交换,也就是说该数列已经排序完成。
  • 这个方法跟快开的水一样,小气泡(较小的数)会慢慢浮到顶端。
  • 特点:交换次数过多,但是稳定。
  • 复杂度分析
    平均时间复杂度:O(n²)
  • 代码实现
public static void sort(int[] a) {
    for (int i = 0; i < a.length - 1; i++) {
        for (int j = 0; j < a.length - i - 1; j++) {
            if (a[j] > a[j + 1]) {
                int temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
            }
        }
    }
}
  • 归并排序
  • 归并排序算法是将几个有序列合并成一个新的有序列,即把待排序序列分为若干个小的序列,将小的序列排序,然后再把有序子序列合并并排序为为整体有序序列。
  • 复杂度分析
    平均时间复杂度:O(nlog₂n)
  • 代码实现:
public class Merge {
private static int[] aux;

public static void sort(int[] a) {
    aux = new int[a.length];
    sort(a, 0, a.length - 1);
}

public static void sort(int[] a, int low, int high) {
    if (low >= high) {
        return;
    }
    int mid = (low + high) / 2;
    sort(a, low, mid);
    sort(a, mid + 1, high);
    merge(a, low, mid, high);
}

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

  • 问题1:归并排序还是不太理解
  • 问题1解决方案:上网找了两张示意图,很清晰

hessian 的数据结构 数据结构compare_hessian 的数据结构

图解排序算法(四)之归并排序

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

  • 问题1:当我在HashLinked类里面定义一个Number型的数组
Number[] n=new Number[20];

然后在类的结构体里初始化n数组时

public HashLinked(int[] a){
    for(int i=0;i<a.length;i++){
        n[i].num=a[i];
    }
}

每次都会报错:

hessian 的数据结构 数据结构compare_赋值_02

  • 问题1解决方案:第一个语句只是声明了一个Number型的数组,此时数组内部都为空(NULL),所以当想要给n[i].num赋值时,就会出现空指针。于是我用了这样的一条语句:
ele[i]=new Number(0);

这样就把数组给初始化了。

hessian 的数据结构 数据结构compare_hessian 的数据结构_03

  • 问题2:在我给Number型的数组赋值后,改变数组中的一个元素的值,所有元素的值都变了。

hessian 的数据结构 数据结构compare_hessian 的数据结构_04

  • 问题2解决方案:其实是我一开始赋值的时候,用了
Number I=new Number(Initial);
for(int i=0;i<ele.length;i++){
    ele[i]=I
}

而这一步不只是赋值给他,并且是将地址都指向了I所在的位置,因此改变这个地址上的数值,数组元素都跟着变了。

hessian 的数据结构 数据结构compare_hessian 的数据结构_05

  • 问题3:在计算程序运行的时间时,输出都为0ms

hessian 的数据结构 数据结构compare_数组_06

  • 问题3解决方法:程序简单,运行时间过短,因此无法用ms来衡量
    将得到时间的语句由
long t1=System.currentTimeMillis();

改为

long t1=System.nanoTime();

就行了。

hessian 的数据结构 数据结构compare_hessian 的数据结构_07

代码托管

hessian 的数据结构 数据结构compare_赋值_08

上周考试错题总结

无考试。

结对及互评

  • 博客中值得学习的或问题:
  • 对上周的错题进行了仔细的更正和课后复习,我对上周考试题的复习较为草率。
  • 博客撰写详细,有理有据。
  • 在撰写博客的过程中可以加入更多自己的理解。
  • 代码中值得学习的或问题:
  • 代码风格良好,便于阅读。
  • 基于评分标准,我给本博客打分:14分。得分情况如下:
  1. 正确使用Markdown语法(加1分):
  • 不使用Markdown不加分
  • 有语法错误的不加分(链接打不开,表格不对,列表不正确...)
  • 排版混乱的不加分
  1. 模板中的要素齐全(加1分)
  • 缺少“教材学习中的问题和解决过程”的不加分
  • 缺少“代码调试中的问题和解决过程”的不加分
  • 代码托管不能打开的不加分
  • 缺少“结对及互评”的不能打开的不加分
  • 缺少“上周考试错题总结”的不能加分
  • 缺少“进度条”的不能加分
  • 缺少“参考资料”的不能加分
  1. 教材学习中的问题和解决过程(2分)
  2. 代码调试中的问题和解决过程(3分)
  3. 本周有效代码超过300分行的(加1分)
  4. 其他加分:
  • 周五前发博客的加1分
  • 感想,体会不假大空的加1分
  • 进度条中记录学习时间与改进情况的加1分
  • 有动手写新代码的加1分
  • 错题学习深入的加1分
  • 点评认真,能指出博客和代码中的问题的加1分
  • 结对学习情况真实可信的加1分

点评过的同学博客和代码

  • 本周结对学习情况
  • 结对同学学号2332
  • 结对照片
  • 结对学习内容
    对上周及本周的考试内容进行了探讨,并通过上网查询等方式深入分析,直到将问题理解。
    一起制作博客,markdown,遇到问题相互询问,并解决。

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

第八周跟第七周博客时间几乎重了,所以没什么新的感想,那就祝学姐越来越漂亮,学长越来越帅吧(小嘴抹了蜜)。

学习进度条

代码行数(实际/预期)

博客量(新增/累积)

学习时间(新增/累积)

重要成长

目标

10000行

第一周

119/119

3/3

20/20

第二周

302/300

2/5

25/45

第三周

780/800

2/7

25/70

第四周

1500/1300

2/9

25/95

第五周

3068/2500

3/12

25/120

第六周

4261/4000

2/14

25/145

第七、八周

7133/7000

3/17

25/170

  • 计划学习时间:25小时
  • 实际学习时间:20小时

参考资料