20162324 2017-2018-1 《程序设计与数据结构》第3周学习总结
教材学习内容总结
这周主要学习的是有关查找和排序的方法。
- 查找
包括了线性查找和二分查找两种方法,分别体现了穷举法和分而治之的两种思想。
算法的复杂度来说线性查找是O(n)而二分查找的算法复杂度是O(log n)所以单单从复杂度上来说二分查找的算法的效率更高,但是二分查找要求序列是有序的,因此有一定的限制,所以不是任何情况下都是二分查找要好,应该视情况而定。
- 排序
对于排序算法来说在书上介绍了5个算法:选择排序、插入排序、冒泡排序、快速排序、归并排序。
再具体介绍排序之前这里列出一个在数组中交换位置的方法,在下面的代码中会使用。
private static void swap (Comparable[] data, int index1, int index2)
{
Comparable temp = data[index1];
data[index1] = data[index2];
data[index2] = temp;
}
- 选择排序
图示:
代码:
public static void selectionSort (Comparable[] data)
{
int min;
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 void insertionSort (Comparable[] data)
{
for (int index = 1; index < data.length; index++)
{
Comparable 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--;
}
data[position] = key;
}
}
- 冒泡排序
图示:
代码:
public static void bubbleSort (Comparable[] data)
{
int position, scan;
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);
}
}
- 快速排序
代码
public static void quickSort (Comparable[] data, int min, int max)
{
int pivot;
if (min < max)
{
pivot = partition (data, min, max); // make partitions
quickSort(data, min, pivot-1); // sort left partition
quickSort(data, pivot+1, max); // sort right partition
}
}
private static int partition (Comparable[] data, int min, int max)
{
// Use first element as the partition value
Comparable partitionValue = data[min];
int left = min;
int right = max;
while (left < right)
{
// Search for an element that is > the partition element
while (data[left].compareTo(partitionValue) <= 0 && left < right)
left++;
// Search for an element that is < the partitionelement
while (data[right].compareTo(partitionValue) > 0)
right--;
if (left < right)
swap(data, left, right);
}
// Move the partition element to its final position
swap (data, min, right);
return right;
}
- 归并排序
合并部分图示:
代码:
public static void mergeSort (Comparable[] data, int min, int max)
{
if (min < max)
{
int mid = (min + max) / 2;
mergeSort (data, min, mid);
mergeSort (data, mid+1, max);
merge (data, min, mid, max);
}
}
public static void merge (Comparable[] data, int first, int mid,
int last)
{
Comparable[] temp = new Comparable[data.length];
int first1 = first, last1 = mid; // endpoints of first subarray
int first2 = mid+1, last2 = last; // endpoints of second subarray
int index = first1; // next index open in temp array
// Copy smaller item from each subarray into temp until one
// of the subarrays is exhausted
while (first1 <= last1 && first2 <= last2)
{
if (data[first1].compareTo(data[first2]) < 0)
{
temp[index] = data[first1];
first1++;
}
else
{
temp[index] = data[first2];
first2++;
}
index++;
}
// Copy remaining elements from first subarray, if any
while (first1 <= last1)
{
temp[index] = data[first1];
first1++;
index++;
}
// Copy remaining elements from second subarray, if any
while (first2 <= last2)
{
temp[index] = data[first2];
first2++;
index++;
}
// Copy merged data into original array
for (index = first; index <= last; index++)
data[index] = temp[index];
}
}
- 其他:
老师在上课时还介绍了希尔排序、桶排序、基数排序等,就不在此一一列举。 - 蓝墨云班课PPT
在罗列出这些算法之后我们对他们的算法复杂度进行比较,下图就比较好的展示了各个算法的各种性能。
教材学习中的问题和解决过程
- 问题1:选择排序与插入排序的区别,课本中提及到两个排序的概念:
选择排序算法是反复的将一个个具体的值放到它最终的有序位置,从而完成一组值得排序。
插入排序算法是反复的将一个个具体的值插入到表的已有序的子表中,从而完成一组值得排序。
这两个概念看起来好像一样,在课下自己学习的时候我无法分清这两个排序,并且没找不同点。
- 问题1解决方案:在上课的时候听老师介绍老师说选择是在有序序列里操作,后来仔细思考之后发现选择排序排出来之后之前的序列是肯定不变,而插入序列就不是,他就是在原本的有序序列之中插入一个元素。所以差别也就出现了。
代码调试中的问题和解决过程
- 主要都是打课本上的的代码没有太多的问题。没有遇到什么大问题。
代码托管
上周考试错题总结
- 课下测试虽然花费的时间有点多,但是在仔细的查阅了资料之后才做的所以就获得了满分。
- 课上测试
设 n 为正整数, 给出下列 3 个算法关于问题规模 n 的时间复杂度。
(3) 算法 3
void fun3(int n)
{ int i=0,s=0;
while (s<=n)
{ i++;
s=s+i;
}
}
结对及互评
本周结对学习情况
- 20162312
- 结对照片
- 结对学习内容
- 主要进行的是有关排序的学习。
- 对于接口的相关知识点进行了复习。
- 对泛型的知识点进行了复习。
其他(感悟、思考等,可选)
这周过的不是很顺心,虽然在学习上没有出什么问题,但是在生活中出现了一些不愉快的事,让我进一步体会了大学的生活,在大学中就是在向社会过渡的一个过程,可能就是要明白我们不能再只以学生的眼光去看待生活。
在学习上我试着阅读全英文的教材虽然需要已经翻译好的课本进行对照,但是对于我的学习还是有一定的帮助,至少印象比只读中文教材要更深一些。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 196/196 | 1/1 | 11/11 | 对于算法有了进一步的了解 |
第二周 | 76/270 | 1/2 | 10/21 | 了解一种新的方法,提高代码的复用性。 |
第三周 | 757/1027 | 2/4 | 10/31 | 了解很多的高效率的排序的方法和两种查找方法 |
-
计划学习时间:10小时
-
实际学习时间:15小时
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)