Java数据结构和算法-作业2-问题部分

序:

    下述的作业题源自<<Java数据结构和算法(第二版)>>每章结束后留给的问题,它们涵盖了每章的所有重点。目地在于自测,以确保自己已经基本理解该章的内容。

 

3章 简单排序

问题

1、  计算机排序算法与人类排序相比较,它的局限性是:D

A、  人类擅长发明新算法。

B、   计算机只能处理数量固定的数据。

C、   人类知道什么需要排序,而计算机不知道。

D、  计算机一次只能比较两件东西。

解:计算机程序不能像人这样通览所有的数据。它只能根据计算机的“比较”操作原理,在同一时间内对两个数据进行比较。

2、  简单排序算法中的两个基本操作是比较两个数据项和交换两个数据项(或复制其中一项)。

解:这一章中的三个算法(冒泡排序、选择排序和插入排序)都包括如下的两个骤,这两步循环执行,直到全部数据有序止:

1、  比较两个数据项。

2、  交换两个数据项,或复制其中一项。

3、  判断题:冒泡排序算法总是在所有数据项两两比较完成后停止。

解:冒泡排序遵循的规则:

1、  比较两个数据项。

2、  如果左边的数据项大,则两数据项交换位置。

3、  向右称动一个位置,比较下面两个队员。

沿着这个队列照刚才那样比较下去,一直比较到队列的最右端。

4、  冒泡排序算法在哪两者之间交替进行:A

A、比较和交换。

B、  移动各复制。

C、  移动各比较。

D、复制和比较。

解:请看判断题3的解。

5、  判断题:有N个数据项,冒泡排序算法精确操作了N*N次比较。

解:算法作了大约N2/2(备注1次比较。

6、  选择排序中B

A、最大的关键字聚集到左边(较小的下标)。

B、  最小的关键字被重复的发现。

C、  为了将每个数据项插入到正确排序的位置,很多数据项将被移动。

D、有序的数据项聚集在右边。

解:进行选择排序就是把所有的数据项扫描一趟,从中挑出最小的关键字。这个最小的关键字和和最左端的数据项交换位置,即站到0号位置。现在最左端的数据项是有序的了。不需要交换位置了。再次扫描所有数据项时,就从1号位置开始,还是寻找最小关键字,然后和1号位置的数据项交换。这个过程一直持续到所有的数据项都排定。

7、  判断题:在某个特定的排序情况中,如果交换与比较相比费时得多,那么选择排序将比冒泡排序快大约一倍。

解:选择排序改进了冒泡排序,将必要的交换次数从ON2)减少到ON)不幸的是比较次数仍保持为ON2)。

8、  复制是交换的倍。

9、  选择排序中不变性是什么?

答:下标小于或等于out的项进行排序。

10、插入排序中,文中描述的“被标记的队员”对应于insertSort.java中的哪个变量?C

A、in

B、  out

C、  temp

D、a[out]

11、在插入排序中,“局部有序”是指:D

A、一些数据项已经排序了,但它们可能需要被移动。

B、  大部分数据项已在它们最终排序的位置了,但仍有一些需要排序。

C、  只有一些数据项有序。

D、组内的数据项已排序好序,而组外面的数据项需要插入到组中来。

12、向左或向右移动一组数据项需要重复地复制

13、在插入排序中,一个数据项被插入到局部有序的组合后,它将:B

A、永远不会再移动。

B、永远不会向左边移动。

C、经常被移出这个组。

D、发现这组的数据项不断减少。

14、插入排序中的不变性是下标小于outer的项部分有序。

15、稳定性是指:B

A、在排序中排除有次关键字的项。

B、  在对州进行排序时,每个州的城市还要求按人口递增有序。

C、  让相同的名配相同的姓。

D、数据项按照关键字有序,不考虑次关键字。

 

编程作业

   3.1 bubbleSort.java程序(清单3.1)和BubbleSort专题applet中,in索引变量都是从左到右移动的,直到找到最大数据项并把它移动到右边的out变量外。修改bubbleSort()方法,使它成为双向移动的。这样,in索引先像以前一样,将最大的数据项从左移到右,当它到达out变量位置时,它掉头并把最小的数据项从右移到左。需要两个外部索引变量,一个在右边(以前的out变量),另一个在左边。

    3.2isertSort.java程序(清单3.3)中给ArrayIns类加一个median()方法.这个方法将返回数组的中间值.(回忆一下,数组中一半数据项比中间值大,一半数据项比中间值小。)

    3.3insertSort.java程序(清单3.3)中增加一个名为noDups()的方法,这个方法从已经有序的数组中删掉重复的数据项而不破坏有序性。(可以用insertionSort()方法对数据排序,或者也可以简单地用main()方法将数据有序地插入到表中。)一种解决方法是每发现一个重复的数据,就从这个位置开始到数组结尾都向前移动一个位置,但这样就导致消耗很长的O(N2)的时间级,起码在有很多重复数据项的情况下是这样的。在设计的算法中,不论有多少重复数据,要确保数据项最多只能移动一次。这样算法只消耗O(N)数量级的时间。

    3.4还有一种简单排序算法是奇偶排序。它的思路是在数组中重复两趟扫描。第一趟扫描选择所有的数据项对,a[j]a[j+1]j是奇数(j=1,3,5,……)。如果它们的关键字的值次序颠倒,就交换它们。第二趟扫描对所有的偶数数据项进行同样的操作(j=2,4,6,……)。重复进行这样两趟的排序直到数组全部有序。用oddEvenSort()方法替换bubbleSort.java程序(清单3.1)中的bubbleSort()方法。确保它可以在不同数据量的排序中运行,还需要算出两趟扫描的次数。

    奇偶排序实际上在多处理器环境中很有用,处理器可以分别同时处理每一个奇数对,然后又同时处理偶数对。因为奇数对是彼此独立的,每一对都可以用不同的处理器比较和交换。这样可以非常快速地排序。

    3.5修改insertSort.java程序(清单3.3)中的insertionSort()方法,使它可以计算排序过程中复制和比较的次数并显示出总数。为计算比较的次数,要把内层while循环的两个条件分开。用这个程序测量各种数量的逆序数据排序的复制和比较次数。结果满足O(N2)吗?与已经基本有序的数据(仅有很少的数据无序)的情况一样吗?从对基本有序数据排序的表现中可得出关于这个算法效率的什么结论?

    问题1用这个程序测量各种数量的逆序数据排序的复制和比较次数。结果满足O(N2)吗?

    答:假设有10个数据项以逆序排列(90)。这个算法需要多少次比较和复制呢?在第一趟排序中,它最多比较一次,第二趟最多比较两次,依此类推。最后一趟最多,比较N-1次。因此有

    1+2+3+…+N-1=N*(N-1)/2(备注1, 10*(10-1)/2 = 45

    复制的次数大致等于比较的次数。在本例中a[in-1]>=temp每次比较都会成立,所以复制操作也将执行。比较和复制操作次数都和N2成正比。并且认为运行需要O(N2)时间级别。

    问题2与已经基本有序的数据(仅有很少的数据无序)的情况一样吗?

    答:给定一个数组,其中数据项按如下所示排列:

0 11 22 44 55 33 66 88 77 99

上述数例排序后比较用了12次、复制3次。对于已经有序或基本有序的数据来说,插入排序要好得多。当数据有序的时候,while循环的条件总是假,所以它变成了外层循环中的一个简单语句,执行N-1次。在这种情况下,算法运行只需要O(N)的时间。如果数据基本有序,插入排序几乎只需要O(N)的时间,这对把一个基本有序的文件时行排序是一个简单而有效的方法。

    问题3从对基本有序数据排序的表现中可得出关于这个算法效率的什么结论?

    答:对于逆序排列的数据,每次比较和移动都会执行,所以插入排序不比冒泡排序快。

    3.6有一个有趣的方法用来删除数组中相同的数据项。插入排序算法中用一个循环嵌套算法,将数组中的每一个数据项与其他数据项一一比较。如果要删除相同的数据项,可以这样做(参见第2章第2.6小节)。修改insertSort.java中的insertionSort()方法,使它可以在排序过程中删除相同的数据项。方法如下:当找到一个重复数据项的时候,通常用一个小于任何值的关键值来改写这个相同数据项(如果所有值都是正数,则可取-1)。于是,一般的插入排序算法就会像处理其他数据项一样,来处理这个修改了关键值的数据项,把它移到下标为0的位置。从现在开始,算法可以忽略这个数据项。下一个相同的数据项将被移到下标为1的位置,依此类推。排序完成后,所有相同的数据项(现在关键值为-1)都在数组的开头部分。可以改变数组的容量并把需要的数据前移动数组下标为0的位置。

答:这个题目我就不做了,没有什么新意。其实就是把noDups()中的代码和insertionSort()代码混合后就能达到上述作业要求。

 

 

 

备注1:在数组数据项的线性查找中,我们已经发现寻找特定数据项所需的比较次数平均为数据项总数的一半。——摘自《Java数据结构和算法(第二版)》第2章数组:大O表示法小节。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值