20172329 2017-2018-2 《程序设计与数据结构》第十周学习总结
20172329 2017-2018-2 《程序设计与数据结构》第十周学习总结
教材学习内容总结
第十三章
-
一、集合与数据结构
1、集合:是一种对象,类似于保存其他对象的存储库;
2、作用:表示一个专用与保存元素的对象,并且该对象还提供增添、删除等管理所保存元素的服务; -
二、集合的同构与异构
1、同构:保存类型全部相同的对象的集合;
2、异构:可以保存各种类型的对象的集合; -
三、分离接口与实现
1、ADT:是由数据和在该数据上所实施的具体操作构成的集合,yigeADT有名称、值域和一组允许执行的操作。
2、其之所以被视为抽象数据类型,是因为在ADT上可以执行的操作与底层的实现分离开了。
3、对象具有定义良好的接口,从而成为一种实现集合的完整机制。 -
四、数据结构的动态表示
1、动态数据结构的大小规模随需要增长和收缩;
2、通过保存和更新对象引用来实现一个链表的管理; -
五、线性数据结构
1、队列:是一种先进先出方式管理数据的线形数据结构;
2、堆栈:是一种以后进先出方式管理数据的线形数据结构; -
六、非线性结构
1、树:是一种以层次结构组织数据的非线性数据结构;
2、图:是非线性数据结构,使用常见的边来连接节点; -
七、Java 集合类
1、Java集合类API定义了几种以不同方式实现的集合类;
教材学习中的问题和解决过程
- 问题1:看到过这样一句话,“数组与链表为同级”,那他们可以互换吗,或者彼此替代吗?
- 问题1解决方案:
首先我们从他们不同的概念和特点来讲:
-
数组的特点
1、在内存中,数组是一块连续的区域。
2、数组需要预留空间,在使用前要先申请占内存的大小,可能会浪费内存空间。 比如看电影时,为了保证10个人能坐在一起,必须提前订好10个连续的位置。这样的好处就是能保证10个人可以在一起。但是这样的缺点是,如果来的人不够10个,那么剩下的位置就浪费了。如果临时有多来了个人,那么10个就不够用了,这时可能需要将第11个位置上的人挪走,或者是他们11个人重新去找一个11连坐的位置,效率都很低。如果没有找到符合要求的作为,那么就没法坐了。
3、插入数据和删除数据效率低,插入数据时,这个位置后面的数据在内存中都要向后移。删除数据时,这个数据后面的数据都要往前移动。 比如原来去了5个人,然后后来又去了一个人要坐在第三个位置上,那么第三个到第五个都要往后移动一个位子,将第三个位置留给新来的人。 当这个人走了的时候,因为他们要连在一起的,所以他后面几个人要往前移动一个位置,把这个空位补上。
4、随机读取效率很高。因为数组是连续的,知道每一个数据的内存地址,可以直接找到给地址的数据。
5、并且不利于扩展,数组定义的空间不够时要重新定义数组。 -
链表的特点
1、在内存中可以存在任何地方,不要求连续。
2、每一个数据都保存了下一个数据的内存地址,通过这个地址找到下一个数据。 第一个人知道第二个人的座位号,第二个人知道第三个人的座位号……
3、增加数据和删除数据很容易。 再来个人可以随便坐,比如来了个人要做到第三个位置,那他只需要把自己的位置告诉第二个人,然后问第二个人拿到原来第三个人的位置就行了。其他人都不用动。
4、查找数据时效率低,因为不具有随机访问性,所以访问某个位置的数据都要从第一个数据开始访问,然后根据第一个数据保存的下一个数据的地址找到第二个数据,以此类推。 要找到第三个人,必须从第一个人开始问起。
5、不指定大小,扩展方便。链表大小不用定义,数据随意增删。 -
综上所述:
我发现同级只是它们的共同点之一,不同仅仅以这样一个标准就去认为可以互换,实际上讲,各个都有彼此的优点,互换的也仅仅是方法,各自有实现目标的办法,只是有些方法复杂,有些比较简单而已,所以讲,从实际问题上讲,是可以互换的,但是不能直接讲位置互换就可以,需要进行方法内部的修改,然后发现问题,及时修改。
ps:就这样问题,其实我在做pp13.3的时候深刻体会的到,因为数组有数组实现排序的方法,而链表也有链表实现排序的方法,就问题来论方法才是我们当今学习Java的主要进步过程,不能盲目去学习。感觉又一波鸡汤,自我安慰,习惯习惯
- 问题2:什么叫做冒泡排序?
- 问题2解决方法:
这个问题是我在看排序的时候发现的,之前总觉得冒泡排序就是链表的插入排序法,后来发现自己太傻了,凭空制造了一个概念,现在我来讲一下我学习这种排序的经历。
一、首先,冒泡排序:
1、原理:比较两个相邻的元素,将值大的元素交换至右端。
2、思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。
3、优点:每进行一趟排序,就会少比较一次,因为每进行一趟排序都会找出一个较大值。如上例:第一趟比较之后,排在最后的一个数一定是最大的一个数,第二趟排序的时候,只需要比较除了最后一个数以外的其他的数,同样也能找出一个最大的数排在参与第二趟比较的数后面,第三趟比较的时候,只需要比较除了最后两个数以外的其他的数,以此类推……也就是说,没进行一趟比较,每一趟少比较一次,一定程度上减少了算法的量。4
例子:
第一种:假如有几个数字int score[] = {67, 69, 75, 88}; 按照从大到小排序。
我们就可以用这个方法进行排序:
for(int i =0;i < score.length - 1;i++)
{
for(int j = 0;j < score.length - 1-i;j++)// j开始等于0,
{
if(score[j] < score[j+1])
{
int temp = score[j];
score[j] = score[j+1];
score[j+1] = temp;
}
}
}
测试结果:
第二种:第二种思路,用88 和 75 比较,在和69 比较 在和 67 比较,发现88是最大的,吧他排到第一位(index=0的位置),然后i=1,也就是第二轮,就不用看下标为0的88了因为他是老大,然后接着比较。;
for(int i =0;i < score.length - 1;i++)
{
for(int j = (score.length - 2);j >= i;j--)
{
if(score[j] < score[j+1])
{
int temp = score[j];
score[j] = score[j+1];
score[j+1] = temp;
}
}
}
测试结果:
ps:我发现这个和pp13.3好像啊,然后就和那个选择排序法好像啊,但是还是不一样,具体体现在一个是左右相邻的元素进行比对,一个是先找到最小的那一个元素再去与那个最小的进行对比再进行排序。
代码调试中的问题和解决过程
- 问题1:
在做pp13.3的时候,最初我想用的方法就是用两个指针,分别指向thisXX
和thisXX.next
,但是在我写完排序程序以后,会发现在第一个循环中,它会吞一些节点;
- 问题1解决方案:
因为是通过一个Boolean对象来判断是否进入下一个循环,所以在排好序以后,他总是又进入第一个大循环里,把之前排好队的对象给一个一个给删了,最后我就把Boolean给删了,然后只留下了一个内循环,只是为了找最小的那一个节点,例:
BUT,又奔出现一个bug,我发现,虽说第一个和第二个参与排序了,但是第一个和第二个没有进行互换,晕.....
我只得用循环外部弄一个在之前课堂作业里和小赵同学一起弄出的方法,加一个互换
如此甚好,问题也就随之解决了。
- 问题2:
就pp13.3的问题,我还想再写一个问题,因为很想知道为什么两个指针就会消去呢,于是第二天我继续写了一个类似的两个指针,可是,奇迹出现了,它竟然,排序成功了,我竟久久不能,不知所措,昨儿,我的半下午一直在调试,没了,半下午就这么没了
- 问题2解决方案:
具体:直接放上代码好了
代码托管
上周考试错题总结
-
错题1
Why is the following method one which has infinite recursion?
public int infiniteRecursion(int n)
{
if (n > 0) return infiniteRecursion(n) + 1;
else return 0;
}
A. Because there is no base case
B. Because the base case will never be true
C. Because the recursive call does not move the parameter closer to the base case
D. Because the recursive call moves the problem further away from the base case
E. None of the above, there is no infinite recursion in this method正确答案: C 我的答案: A
解析:递归的情况下,该方法使用相同的参数调用自己,所以n不会改变,因此如果(n> 0)最初为真,它将保持为真。
-
错题2
If there are 2 disks to move from one Tower of Hanoi to another, how many disk movements would it take to solve the problem using the recursive solution?
A. 0
B. 1
C. 2
D. 3
E. 4正确答案: D 我的答案: B
解析:Hanoi解决方案需要使用以前的解决方案两次+ 1次额外的移动。要解决它1个磁盘,它需要1移动。要解决它的2个磁盘,它需要使用解决方案1个磁盘两次+1,或1移动+ 1移动+ 1移动= 3移动。我们在等式2 ^ n - 1中捕获它,其中n是磁盘的数量。
-
错题3
If there are 6 disks to move from one Tower of Hanoi to another, how many disk movements would it take to solve the problem using the recursive solution?
A. 6
B. 13
C. 31
D. 63
E. 127正确答案: D 我的答案: A
解析:Hanoi解决方案需要使用以前的解决方案两次+ 1次额外的移动。要解决它1个磁盘,它需要1移动。要解决它的2个磁盘,它需要使用解决方案1个磁盘两次+ 1个额外的移动,或1移动+ 1移动+ 1额外移动= 3个移动。我们在等式2 ^ n - 1中捕获它,其中n是磁盘的数量。对于3个磁盘,这需要7次移动,对于4个磁盘需要15次移动,对于5个磁盘需要31次移动,对于6个磁盘,这需要63次移动。
-
错题4
The difference between direct and indirect recursion is
A. direct recursion occurs when a method invokes itself; indirect recursion occurs when there is an intervening method
B. indirect recursion occurs when a method invokes itself; direct recursion occurs when there is an intervening method
C. direct recursion only occurs with methods declared to be private; indirect recursion can occur with methods declared to be private, protected, or public
D. indirect recursion only occurs with methods declared to be private; direct recursion can occur with methods declared to be private, protected, or public
E. none of the above正确答案: A 我的答案: B
解析:直接递归意味着一种方法直接调用自己而不需要插入方法。间接递归在原始方法再次调用之前有一个或多个中介方法时发生。
-
错题5
It always is possible to replace a recursion by an iteration and vice versa.
A. true
B. false正确答案: A 我的答案: B
解析:递归和迭代都是重复的形式。无论是使用递归还是迭代来重复重复都是风格,品味,有时效率,有时方便。但它们在计算方面是等价的 - 每一个都可以被另一个替代。
结对及互评
- 本周结对学习情况
- 博客中值得学习的或问题:
- 内容详略得当;
- 代码调试环节比较详细;
- 基于评分标准,我给本博客打分:5分。得分情况如下:
-
正确使用Markdown语法(加1分):
-
模板中的要素齐全(加1分)
-
教材学习中的问题和解决过程, 一个问题加1分
-
代码调试中的问题和解决过程, 一个问题加1分
- 博客中值得学习的或问题:
- 内容详略得当;
- 代码调试环节比较详细;
- 基于评分标准,我给本博客打分:9分。得分情况如下:
- 正确使用Markdown语法(加1分):
- 模板中的要素齐全(加1分)
- 教材学习中的问题和解决过程, 一个问题加1分
- 代码调试中的问题和解决过程, 一个问题加1分
感想
突然发现已经敲了半个多学期的代码了,时间总是在不经意间失去,其实,无论是一个人敲代码,还是完成集体的结对编程,考验的终究是我们自己的能力,合作能力,编程能力,有时候总是觉得自己不行,拖后腿,有时候在写博客的时候总是抱怨,有没有什么问题,还要找问题,但是其实细细的想,或许问题不是出在自己编的某一个程序里,而是出在整个学习的过程中呢?因为其实从一些实验,作业中,其实都可以透露出别人的影子,但有时还要强作是自己绞尽脑汁想出来的,我记得高中老师给我们这么说:“借鉴,其实就是一种变相的抄袭,虽说不是完全抄,但是你借取的还是别人的经验,自己只是负责修改。”的确是这样,课程难,大家都累,每天看着那密密麻麻的代码,有些人觉得它就是世界上最美的语言,而有些人,仅仅把它看作以后,未来盈利的一种工具,或是自己上位的一种能力,我们大家都应该反思,为了什么而学习。只剩下半学期的学习时间,大家可以以一个积极的方式去学习,不是只是盲目追求着一个目标,事到临头的时候就仿照别人的写一个,所以合理分配时间,制定方案,计划,进行合理学习,创造更多的自我价值。
加油!!
学习进度条
| | 代码行数(新增/累积)| 博客量(新增/累积)|学习时间(新增/累积)
| -------- | :----------------😐:----------------😐:---------------: |:-----:
| 目标 | 5000行 | 30篇 | 400小时
| 第一周 | 156/156 | 1/1 | 15/15
| 第二周 | 217/371 | 1/2 | 20/35
| 第三周 | 233/604 | 2/4 | 20/55
| 第四周 | 1382/1986 | 1/5 | 35/90
| 第五周 | 146/2196 | 1/6 | 25/115
| 第六周 | 462/2658 | 1/7 | 15/130
| 第七周 |856/3514 | 1/8 | 20/150
|第八周 | 1877/5391 | 3/11 |20/170
|第九周 | 1747/7138 | 1/12 | 20/190
|第十周 | 1323/8461 |2/14| 30/220
参考资料
Java程序设计
蓝墨云
数组和链表的区别
单向链表(单链表)的Java实现
Java实现单向链表的归并排序
冒泡排序的2种写法
Java中的经典算法之冒泡排序(Bubble Sort)