20172324 2018-2019-1 《程序设计与数据结构》第五周学习总结
20172324 2018-2019-1 《程序设计与数据结构》第五周学习总结
教材学习内容总结
查找
- 概述
-
在某个项目中寻找某一指定目标,或者确定该目标并不存在。
-
两种常见的查找方式有线性查找和二分查找,目标是尽可能高效地完成查找。
public class Searching<T extends Comparable>
算法的实现是一个对象和另一个对象进行比较,其实现方法是对某个Comparable对象的数组进行查找。最好将所有方法声明为静态或者是泛型的。
- 如何查找
-
静态方法
静态方法不能引用实例变量,但可以引用静态变量。 -
泛型方法
不是创建一个引用泛型参数的类,而是一个方法,泛型参数只用于该方法。 -
线性查找法
- 在待查数据中进行顺序性轮询查找,当存在待查的数据时返回当前数据索引位置,如果不存在则返回不存在表示-1
- 平均查找长度: 1/2(n+i)
计算方式:为当前元素查找到的概率乘上所匹配的次数 - 代码实现
-
//线性法查找
boolean linearSearch(T[] data, int min, int max, T target)
{
int index = min;
boolean found = false;
while (!found && index <= max)
{
found = data[index].equals(target);
index++;
}
return found;
}
- 二分查找法
- 特点是待查询的表为有序表。从排序列表的中间开始查找。二分查找每一次比较都会删掉一半的可行候选项。
- 平均查找长度: (n+1/n)*(log2(n+1))-1
- 代码实现
//二分法查找
public static <T extends Comparable<? super T>>
boolean binarySearch(T[] data, int min, int max, T target)
{
boolean found = false;
int midpoint = (min + max) / 2; // determine the midpoint
if (data[midpoint].compareTo(target) == 0)
found = true;
else if (data[midpoint].compareTo(target) > 0)
{
if (min <= midpoint - 1)
found = binarySearch(data, min, midpoint - 1, target);
}
else if (midpoint + 1 <= max)
found = binarySearch(data, midpoint + 1, max, target);
return found;
}
-
查找算法的比较
线性查找比二分查找简单,编程和调试起来更为容易;线性查找无需花费额外成本进行排序。 -
排序
- 顺序排序
使用了一对嵌套循环,为了对一个含n个元素的列表排序,需要进行大概n^2次比较操作。
- 顺序排序
-
选择排序
通过反复将某一特定值放到它在列表里的最终已排序位置从而完成对某一列表值的排序
//选择排序
public static <T extends Comparable<T>>
void selectionSort(T[] data)
{
int min;
T temp;
for (int index = 0; index < data.length-1; index++)
{
min = index;
for (int scan = index+1; scan < data.length; scan++)
if (data[scan].compareTo(data[min])<0)
min = scan;
swap(data, min, index);
}
}
在确定出最小值之后,还有一个值的交换,用下面三个赋值语句实现,称之为互换
- 插入排序
选择一个数组中的数据,通过不断的插入比较最后进行排序。
//插入排序
public static <T extends Comparable<T>>
void insertionSort(T[] data)
{
for (int index = 1; index < data.length; index++)
{
T key = data[index];
int position = index;
// shift larger values to the right
while (position > 0 && data[position-1].compareTo(key) > 0)
{
data[position] = data[position-1];//把数值大的数换到了右边
position--;//position变成左边数的索引
}
data[position] = key;
}
}
- 冒泡排序
运用遍历数组进行比较,通过不断的比较将最小值或者最大值一个一个的遍历出来。
//冒泡排序
public static <T extends Comparable<T>>
void bubbleSort(T[] data)
{
int position, scan;
T temp;
for (position = data.length - 1; position >= 0; position--)
{
for (scan = 0; scan <= position - 1; scan++)
{
if (data[scan].compareTo(data[scan+1]) > 0)
swap(data, scan, scan + 1);
}//第一个循环里面是第一次两个两个比较到列表末尾
}//第二个循环里面是一共进行内循环的次数,其次数与列表元素个数-1相等
}
- 对数排序
- 快速排序
通过使用一个任意选定的分区元素将该列表分区,然后对这两个分区列表进行递归式排序,从而完成对整个列表的排序。 - 归并排序
通过将列表递归式分至两半直至每一子列表里都只含有一个元素,然后再将子列表按顺序重组。
- 基数排序法
无需进行元素之间的相互比较来排序,是通过队列处理的。运用了桶式法
教材学习中的问题和解决过程
-
问题1:不是特别能理解书上说的基数排序,而且看图的时候不知道先排的是,个位数还是百位数才能使这10个数完成排序。
-
问题1解决方案:
在网上找了一个比较清楚的例子:通过基数排序对数组{53, 3, 542, 748, 14, 214, 154, 63, 616},它的示意图如下:
在上图中,首先将所有待比较数字统一为统一位数长度,接着从最低位开始,依次进行排序。
- 按照个位数进行排序。
- 按照十位数进行排序。
- 按照百位数进行排序。
排序后,数列就变成了一个有序序列。
-
问题2:
public static <T extends Comparable<? super T>>
书本上的这个代码<? super T>到底是什么意思,是否可以删掉?
- 问题2解决方案:我理解的? super T应该是所编写的某类型可以继承泛型T,但理解起来很牵强。上网:
这里来分析T表示任意字符名,extends对泛型上限进行了限制即T必须是Comparable<? super T>的子类,
然后<? super T>表示Comparable<>中的类型下限为T!
那么泛型上限和类型下限又是什么???
对于是否能删掉的问题,这样来看一段代码辅助理解:
class Demo<T extends Comparable<? super T>>{}
public class Test1
{
public static void main(String[] args) {
Demo<GregorianCalendar> p = null; // 编译正确
}
}
解释:
这个可以理解为<GregorianCalendar extends Comparable<Calendar>>是可以运行成功的!因为Calendar为GregorianCalendar 的父类并且GregorianCalendar 实现了Comparable<Calendar>,可查看api!.
如果是如下代码则运行不成功:
class Demo<T extends Comparable<T>>{}
//这里把? super去掉了
public class Test
{
public static void main(String[] args) {
Demo<GregorianCalendar> p = null;
}
}
解释:
编译会报错!因为<T extends Comparable<T>>相当于<GregorianCalendar extends Comparable<GregorianCalendar>>但是GregorianCalendar并没有实现Comparable<GregorianCalendar>而是实现的Comparable<Calendar>,这里不在限制范围之内所以会报错!
总结:
1. 使用?可以接收任意泛型对象。
2. 泛型的上限:?extends 类型。
3. 泛型的下限:?super 类型。
代码调试中的问题和解决过程
-
问题一:在编写pp9.2的时候出现了这样一个问题,提示跳出索引值了
-
问题一解决方案:一步步调试之后发现有这样一个问题,for循环里定义的scan的范围本应该是scan < data.length - position,但是编写代码的时候写成了scan <+ data.length - position,导致数组越界的情况一直发生。还有一个地方就是没有按照题意将间隔的数字慢慢减至1,需要在内层循环完成之后添加I--的条件。
代码托管
上周考试错题总结
-
The elements of an _____________ are kept in whatever order the client chooses.
A .Ordered list
B .Unordered list
C .Indexed list
D .None of the above
.....?我为啥会选c啊,肯定粗心选错了555 -
The Java Collections API contains _________ implementations of an indexed list.
A .Two
B .Three
C .Four
D .Five
原话在书上120页,Java集合API中含有索引列表的三种实现。 -
An interface name can be used to declare an object reference variable. An interface reference can refer to any object of any class that implements the interface.
A .True
B .False
又是书上原话...题目中还有类似得问题....
点评过的同学博客和代码
- 本周结对学习情况
- 结对同学学号21
- 内容详略得当;
代码调试环节比较详细,出现得问题都差不多。
其他(感悟、思考等,可选)
🌫
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0 | 1/1 | 20/20 | |
第二周 | 300/500 | 1/2 | 18/38 | |
第三周 | 300/600 | 1/3 | 18/56 | |
第四周 | 400/1000 | 2/5 | 18/74 | |
第五周 | 300/1300 | 1/6 | 18/92 |