20162321王彪 2017-2018-1 《程序设计与数据结构》第三周学习总结
查找与排序
1.教材知识点总结
- 查找是在一组项内找到指定目标或是确定目标不存在的过程。
- 高效的查找是的比较的次数最少。
- Comparable接口允许多态实现算法,而不是只应用于特定的类。
- 二分查找利用了查找池有序的这个特性。
- 二分查找的每次比较都排除乐一半的可行候选数据。
- 排序是按某种标准将一列数据项按确定的次序重排的过程。
- 选择排序算法反复地将一个个地具体的值插入到表的已有序的子表中,从而完成一组值的排序。
- 冒泡排序算法反复地比较相邻元素,如果必要就交换他们的次序,从而完成一组值的排序。
- 快速排序算法通过划分表,然后再递归地对两个子表进行排序,从而完成一组值的排序。
- 归并排序算法递归地将表平分为两部分,知道每个子表中只含有一个元素,然后将这些子表归并为有序段,从而完成一组值的排序。
- 二分查找有对数阶的复杂度,对于大的查找池来说,这非常有效率。
- 选择排序、插入排序及冒泡排序的平均时间复杂度是O(n²)。
- 快速排序的关键是选择一个好的划分元素。
- 归并排序的最坏运行时间复杂度是O(nlogn).
2.线性查找
关键代码理解
public static Comparable linearSearch (Comparable[] data,Comparable target){
Comparable result = null;
int index =0;
while(result == null&&index <data.length){
if(data[index].compareTo(target)==0)
result =data[index];
index++;
}
return result
}
...
Contact found = (Contact)Searching.linearSearch(player,target);
- linearSearch方法的参数和返回值类型都是Comparable对象,但实际我们确是用着个方法来查找的是Contact对象。这是多态性能的一个例子。任何实现Comparable接口的类的对象都可赋予指向Comparable对象的引用,什么意思?
书中P259:在声明对象引用变量时,可以使用类名作为类型。同样,接口名也可用作引用变量的类型。接口引用变量可用来指向实现该接口的任意类的任何对象
public interface wang{
public void speak();
}
//可以用接口名wang来声明一个对象引用变量
wang biao;
//引用变量biao可以指向实现wang接口的任意类的任何对象。
//假定有个类student实现类接口wang
biao = new student();
-
本例中contact类实现了接口Comparable,所以在代码中出现了```Contact found = (Contact)Searching.linearSearch(players,target);
-
while循环data数组中的元素,每次循环,data数组的一个元素都会和target进行比较,而比较的方法在实现Comparable接口的类Contact已经重写.最后返回一个Conparable对象。
-
线性性查找不要求查找池中的元素按某种特定的次序保存在数组中。但必须能基于Comparable的实现,按顺序一次检查一个值,所以查找的效率不高。
3.二分查找
关键代码
- 二分查找在数学中的使用很多,比如用来开根号等。而实现二分查找的代码就是实现数学的二分法过程
- 试例
public class Binary {
public float answer(int item){
float first = getnum(item);
float last = first+1;
float mid = (first+last)/2;
float firsts = first*first;
float lasts = last*last;
float mids = mid*mid;
for (int i=0;i<4;i++){
if (mids>item){
last = mid;
lasts = mids;
mid = (first+last)/2;
mids = mid*mid;
}
if (mids<item){
first = mid;
firsts = first*first;
mid = (first+last)/2;
mids= mid*mid;
}
}
return mid;
}
public void testgetnum(int i){
System.out.println(getnum(i));
}
public static int getnum(int item){
int num=0;
int front=num*num;
int after=(num+1)*(num+1);
while ((front<item&&after<item)||(front>item&&after>item)){
num++;
front=num+num;
after=(num+1)*(num+1);
}
return num;
}
}
- 课堂代码
int first =0,last=data.length-1,mid
while(result == null&&first<=last){
mid = (first+last) / 2 ;
if(data[mid].comparable(target)==0)
result = data[mid];
else
if(data[mid].compareTo(target)>0)
last = mid -1;
else
first = mid +1;
}
- 代码本身没难度,关键在于每次比较和会改变可行候选者的位置,如果中间值小于查找值,则last变化为mid-1;如果中间值大于查找值,则说明查找值不在中间值为界的前半区,所有first变化为mid+1.
4.排序元素
- 选择排序算法的一般策略是:扫描整个表,找到最小值。将这个值与表中的第一个位置的值相交换。接着扫描除了第一个元素之外的所有值,找的最小值,与表中的第二个位置交换,循环上述步骤,交换的三,四...个元素直到排序完成。
- 插入排序算法的一般策略是:对表中最前面的两个元素进行排序,如果有必要就进行交换,将表中的第三个值插入到前两个(已有序)值组成的子段中的合适位置。接下来将第四个值插入到前三个值的合适位置...
5.结对编程
-
这周的Java课上有了一次实验,较简单,但没做出来,这是最尴尬的。课下和结对编程伙伴两人用他的电脑花了一点时间再次做了这个实验。过程中感觉的伙伴的编程能力还需要提高,虽然自己也强不到哪里去0.0,使用一台电脑,两人一起编,虽然我说的比较多,但效果还凑合......本来以为这次实验和实验博客就差不多完工0.0,伙伴的电脑烧了,0.0
-
这周课上表现很是不好,感觉一些编程能力有了下滑,一些知识点不牢固,IDEA的junit调试被自己弄出了问题,总之还需努力。