【数据结构入门精讲 | 第九篇】考研408排序算法专项练习(一)

前面几篇文章介绍的是排序算法,现在让我们开始排序算法的专项练习。

目录

判断题

1.希尔排序是稳定的算法。(错)

解析:稳定性是指如果两个元素在排序前后的相对顺序保持不变,那么这个排序算法就是稳定的。对于具有相同关键字的元素,排序后它们的相对位置应该保持不变。
2.仅基于比较的算法能得到的最好的"最坏时间复杂度"是O(NlogN)。(对)
3.对N个记录进行归并排序,归并趟数的数量级是O(NlogN)。(错)

答案:O(logN)
4.对N个不同的数据采用冒泡排序进行从大到小的排序,当元素基本有序时交换元素次数肯定最多。(错)

解析:当元素已经基本有序时,冒泡排序的时间复杂度会变得比较低,因为只需要进行少量的交换操作就可以将序列排好序。
5.插入排序算法在每一趟都能选取出一个元素放在其最终的位置上。 (错)

解析:每次插入操作只会将一个元素插入到已经排序好的子序列中,而不是所有元素都放到最终位置上。
6.对N个记录进行简单选择排序,比较次数和移动次数分别为O(N^2)和O(N)。(对)

解析:简单选择排序的基本思想是:每一轮从待排序的序列中选取最小的元素,将其与序列的第一个元素交换位置,然后在剩余的元素中继续寻找最小值,重复上述过程直到序列排好序为止。
7.对N个记录进行快速排序,在最坏的情况下,其时间复杂度是O(NlogN)。(错)

在最好情况和平均情况下,快速排序算法时间复杂性为O(NlogN);在最坏的情况下,其时间复杂度是O(N^2)
8.采用递归方式对顺序表进行快速排序,每次划分后,先处理较短的分区可以减少递归次数。(错)

解析:快速排序的性能与划分后两个子序列的大小无关,在最坏的情况下,仍然可能出现O(N^2)的时间复杂度。
9.空间复杂度:堆排序<快速排序<归并排序(对)
10.堆排序的时间复杂度为O(nlogn),空间复杂度为O(1)(对)
11.要从50个键值中找出最大的3个值,选择排序比堆排序快。(对)
12.计数排序是一个广泛使用的排序算法。对n个分布在[0, m]的整数进行计数排序,时间复杂度为 ()

A.O(m)

B.O(n logn)

C.O(n)

D.O(m+n)

选C
13.在简单选择排序过程中,关键字比较的次数与记录的初始排列次序无关。(对)

选择题

1.有组记录的排序码为{46,79,56,38,40,84 },采用快速排序(以位于最左位置的对象为基准)得到的第一次划分结果为:

A.{40,38,46,56,79,84}

B.{38,46,56,79,40,84}

C.{38,79,56,46,40,84}

D.{38,46,79,56,40,84}

选A,解析:

复制代码
46,79,56,38,40,84
l                  r
因为以46为基准,所以l不动,对r进行分析
84大于46,所以不用动
接着r--,对应40
46,79,56,38,40,84
l              r
40小于46,所以将40替换46
40,79,56,38,------,84
l              r
接着l++
40,79,56,38,------,84
    l          r
l对应79,大于40,所以79替换到r的地方
40,------,56,38,79,84
    l          r
接着r--,对应38
40,------,56,38,79,84
    l       r
38小于40,所以38替换到l的地方
40,38,56,------,79,84
    l       r
接着l++ 
40,38,56,------,79,84
        l   r
l对应56,大于40,所以56替换到r处
40,38,------,56,79,84
        l   r
接着r--
此时l与r位置相同
所以不用替换,直接把基准值46填进去就行

2.使用快速排序算法对数据进行升序排序,若经过一次划分后得到的数据序列是 68, 11, 70, 23, 80, 77, 48, 81, 93, 88,则该次划分的枢轴是:

A.81

B.70

C.80

D.11

选A,解析:枢轴的左边比它小,右边比它大。
3.在基于比较的排序算法中,哪种算法的最坏情况下的时间复杂度不高于O(NlogN)?

A.冒泡排序

B.希尔排序

C.快速排序

D.归并排序

选D,上文讲过了。
4.在快速排序的一趟划分过程中,当遇到与基准数相等的元素时,如果左右指针都会停止移动,那么当所有元素都相等时,算法的时间复杂度是多少?

A.O(N)

B.O(NlogN)

C.O(logN)

D.O(N2)

选A,解析:指针停止就会不断交换左右指针的元素,这样虽然多余的交换次数变多,但让子序列的元素相对平均,所以一共有logN次划分,时间复杂度是O(N)。
5.对数据进行排序时,若采用直接插入排序而不采用快速排序,则可能的原因是

I. 大部分元素已有序

II. 待排序元素数量很少

III. 要求空间复杂度为O(1)

IV. 要求排序算法是稳定的

二者区别如下:直接插入排序是一种简单的排序算法,它的思想是将待排序序列分为已排序和未排序两部分,每次从未排序部分取出一个元素,插入到已排序部分的合适位置。快速排序是一种分治法的排序算法,它通过选择一个基准值,将序列划分为比基准值小和比基准值大的两部分,然后对这两部分进行递归排序。

直接插入排序是稳定的排序算法,相等元素的相对顺序不会改变。快速排序是不稳定的排序算法,相等元素的相对顺序可能会改变。

故本题选I、II、III、IV
6.采用递归方式对顺序表进行快速排序,下列关于递归次数的叙述中,正确的是:

A.每次划分后,先处理较长的分区可以减少递归次数

B.递归次数与初始数据的排列次序无关

C.递归次数与每次划分后得到的分区处理顺序无关

D.每次划分后,先处理较短的分区可以减少递归次数

选C,解析:无论是先处理长分区还是先处理短分区,递归次数均不变。

7.选择一个排序算法时,除算法的时空效率外,下列因素中,还需要考虑的是:

  • I、数据的规模
  • II、数据的存储方式
  • III、算法的稳定性
  • IV、数据的初始状态
    答案:全选。

8.在快速排序的一趟划分过程中,当遇到与基准数相等的元素时,如果左指针停止移动,而右指针在同样情况下却不停止移动,那么当所有元素都相等时,算法的时间复杂度是多少?

答案:O(N^2)

复制代码
比如说
1 1 1 1 1 1 1 1 .... 1 1 1(共n个)
  
i                        j
由于i不动,所以j一直左移,左移n-1次
第一次完成后变为
1 1 1 1 1 1 1 1 .... 1 1 1(共n个)
  i                      j
由于i不动,所以j一直左移,左移n-2次
由此一直递归
则次数为
n-1 + n-2 + n-3 + n-4 + n-5 + n-6 + ....

9.排序过程中,对尚未确定最终位置的所有元素进行一遍处理称为一"趟"。下列序列中,不可能是快速排序第二趟结果的是:

A.5, 2, 12, 28, 16, 32, 72, 60

B.5, 2, 16, 12, 28, 60, 32, 72

C.2, 16, 5, 28, 12, 60, 32, 72

D.2, 12, 16, 5, 28, 32, 72, 60

答案选A

解析

复制代码
先按升序和降序排序
2 5 12 16 28 32 60 72
72 60 32 28 16 12 5 2

因为这题的答案趋势为小的数在左边,大的数在右边
所以我们将升序序列与答案作比较
经过两次快速排序之后,可能的是:
1.产生两个基准,第一个基准要不然在最左要不然在最右,剩下一个基准任意
2.产生三个基准,第一个基准在中间,剩下两个分别在两边

2 5 12 16 28 32 60 72
A(5, 2, 12, 28, 16, 32, 72, 60)
我们发现A选项有12、32与升序序列是对应的
可12和32都不在最左或最右,所以A错


接着看B
2 5 12 16 28 32 60 72
B.5, 2, 16, 12, 28, 60, 32, 72
我们发现B选项有28、72与升序序列是对应的
所以B可能对

看C
2 5 12 16 28 32 60 72
C.2, 16, 5, 28, 12, 60, 32, 72
C中有2、72是对应的,同理C可能正确

看D
2 5 12 16 28 32 60 72
D.2, 12, 16, 5, 28, 32, 72, 60
D中有2、28、32是对应的,同理D可能正确

10.设数组 S[ ]={93, 946, 372, 9, 146, 151, 301, 485, 236, 327, 43, 892},采用最低位优先(LSD)基数排序将 S 排列成升序序列。第 1 趟分配、收集后,元素 372 之前、之后紧邻的元素分别是:

A.485,301

B.301,892

C.236,301

D.43,892

基数排序是一种稳定的排序方法。由于采用最低位优先(LSD) 的基数排序,即第1趟对个位进行分配和收集的操作(按最低位进行排序),因此第一趟 分配和收集后的结果是{151, 301, 372, 892, 93, 43,485, 946, 146, 236, 327,9},元素372之前、之后紧邻的元素分别是301和892,故选B。
11.使用二路归并排序对含 n 个元素的数组 M 进行排序时,二路归并操作的功能是:

A.将两个有序表合并为一个新的有序表

B.将 M 划分为两部分,两部分的元素个数大致相等

C.将 M 划分为两部分,一部分元素的值均小于另一部分元素的值

D.将 M 划分为 n 个部分,每个部分中仅含有一个元素

选A,解析:二路归并排序(Two-way Merge Sort)是归并排序的一种常见实现方式。它将待排序序列不断地划分成两个子序列,然后对每个子序列进行排序,并最后将两个有序的子序列合并起来,从而得到完全有序的序列。
12.给定初始待排序列{ 15,9,7,8,20,-1,4 }。如果希尔排序第一趟结束后得到序列为{ 15,-1,4,8,20,9,7 },则该趟增量为:

A.1

B.4

C.2

D.3

选B,解析:序列中相距4个位置相对应的元素为{ 15,20 }、{ 9,-1 }、{ 7,4 }、{ 8, }。通过比较和交换操作,可将这些元素序列调整为{ 15,-1,4,8,20,9,7 }。
13.对于7个数进行冒泡排序,需要进行的比较次数为:

A.7

B.14

C.21

D.49

选C,解析:冒泡排序的比较次数可以通过以下公式计算:(n-1) + (n-2) + ... + 2 + 1 = n*(n-1)/2,故本题比较次数为21。
14.对于10个数的简单选择排序,最坏情况下需要交换元素的次数为:

A.100

B.45

C.36

D.9

选D,解析:简单选择排序在最坏情况下,会经过n-1次选取最值,才能完成排序。

选择排序图示:

15.对一组包含10个元素的非递减有序序列,采用直接插入排序排成非递增序列,其可能的比较次数和移动次数分别是:

A.100, 100

B.54, 63

C.100, 54

D.45, 44

选D,解析:当元素均为逆序时,插入排序执行的比较和交换次数为n*(n-1)/2,但本题可以考虑有两个元素相同的情况,所以移动次数可以比45少1。

16.对初始数据序列{ 8, 3, 9, 11, 2, 1, 4, 7, 5, 10, 6 }进行希尔排序。若第一趟排序结果为( 1, 3, 7, 5, 2, 6, 4, 9, 11, 10, 8 ),第二趟排序结果为( 1, 2, 6, 4, 3, 7, 5, 8, 11, 10, 9 ),则两趟排序采用的增量(间隔)依次是:

A.5, 2

B.5, 3

C.3, 2

D.3, 1

选B,解析如下:
17.对N个不同的数据采用冒泡算法进行从大到小的排序,下面哪种情况下肯定交换元素次数最多?

A.从大到小排好的

B.元素无序

C.元素基本有序

D.从小到大排好的

选D,解析:当元素基本有序时,交换元素元素较少,冒泡排序交换次数较少。同理可知,当元素从小到大排好时冒泡排序处于最坏情况。
18.对于序列{ 49,38,65,97,76,13,27,50 },按由小到大进行排序,下面哪一个是初始步长为4的希尔排序法第一趟的结果?

A.97,76,65,50,49,38,27,13

B.49,13,27,50,76,38,65,97

C.49,76,65,13,27,50,97,38

D.13,27,38,49,50,65,76,97

选B,解析:按步长为4划分,则有{49,76},{38,13},{65,27},{97,50}

组内排序得到{49,76},{13,38},{27,65},{50,97}

故第一趟的结果为B
19.输入10^6个只有一位数字的整数,可以用O(N)复杂度将其排序的算法是:(桶排序)

解析:桶排序所需的时间复杂度为O(N)
20.若数据元素序列{ 12, 13, 8, 11, 5, 16, 2, 9 }是采用下列排序方法之一得到的第一趟排序后的结果,则该排序算法只能是:(归并排序)

A. 快速排序

B. 选择排序

C. 堆排序

D. 归并排序

解析:排除选择排序,因为选择排序后,最前面一定是最小的或最大的;排除快速排序,因为找不到枢纽值;排除堆排序,建堆后可看出不符合
21.在内部排序时,若选择了归并排序而没有选择插入排序,则可能的理由是:(3)

1 归并排序的程序代码更短

2 归并排序占用的空间更少

3 归并排序的运行效率更高
22.设有1000个元素的有序序列,如果用二分插入排序再插入一个元素,则最大比较次数是:

A.10

B.500

C.1000

D.999

选A,解析:2^10=1024>1000
23.对N个记录进行归并排序,空间复杂度为:O(N)(对)
24.令 n 表征问题规模,下列程序段的时间复杂度是( )。

x=0;

while((x+1)*(x+1)<=n^3)

x=x+1;

A.O(log n)

B.O(n^(3/2))

C.O(n^2)

D.O(n)

选B,x+1<=n^(3/2)

25.解析:2^11=2048

26.计数排序O(n),归并排序O(nlogn)

所以A

填空题

{46 79 56 38 40 84}以46为基准进行快速排序,则第一次的结果为?

复制代码
46与84换 得到
84 79 56 38 40 46
接着左指针从84开始向右找比46大的数  右指针从46开始向左找比46小的数
故84与40换 得到
40 79 56 38 84 46
接着79与38换
40 38 56 79 84 46
现在两个指针都在56 不需要换
因此将46插入38后面即可得到第一次的结果

1.插入排序

排序方法中,从未排序序列中依次取出元素与已排序序列中的元素进行比较,将其放入已排序序列的正确位置的方法称为:(插入排序)

2.另类选择排序

3.冒泡排序

本题要求用冒泡排序将一组整数按增序排序。冒泡排序每次从头到尾扫描待排序列,检查相邻两数的顺序,如果顺序不对就交换。请补全下列冒泡排序的代码。

c 复制代码
typedef struct node *nodeptr;
struct node{
   int value;
   nodeptr next;
   /* 一些其他的项,在此忽略 */
};
 
nodeptr BubbleSort (nodeptr h)
{/* h 是带空头结点的链表的头指针 */
   nodeptr p, q;
   int flag_swap;
 
   if (!h->next)  return h;
   do{
      flag_swap = 0;
      p = h;
      while (p->next->next){
         if ( p->next->value>p->next->next->value (3分) ){
            flag_swap++;
            q = p->next;
            p->next=q->next (3分);
            q->next=p->next->next (3分);
            p->next->next=q (3分);
         }
         else p = p->next;
      }
   } while (flag_swap > 0);
   return h;
}

4.快速查找第K大元

本函数的功能是从有N个元素的线性表A中查找第K大的元素。函数的初始调用为Qselect(A, K, 0, N-1)。请完成下列填空。

c 复制代码
ElementType Qselect( ElementType A[], int K, int Left, int Right )
{
    ElementType Pivot = A[Left];
    int L = Left, R = Right+1;
      
    while (1) {
        while ( A[++L] > Pivot ) ;
        ________________________
//填while ( A[--R] < Pivot )
        if ( L < R ) Swap( &A[L], &A[R] );
        else break;
    }
    Swap( &A[Left], &A[R] );
    if ( K < (L-Left) )
        return Qselect(A, K, Left, R-1);
    else if ( K > (L-Left) )
    ________________________
//填return Qselect(A, K-(L-Left), L, Right)
    else
        return Pivot;
}

至此,我们完成了排序算法的排序、选择、填空的相关练习,在下一篇文章中我们将进行排序算法编程题的练习。

相关推荐
勇闯逆流河7 小时前
【数据结构】堆
c语言·数据结构·算法
pystraf7 小时前
LG P9844 [ICPC 2021 Nanjing R] Paimon Segment Tree Solution
数据结构·c++·算法·线段树·洛谷
Nobkins9 小时前
2021ICPC四川省赛个人补题ABDHKLM
开发语言·数据结构·c++·算法·图论
易只轻松熊11 小时前
C++(23):容器类<vector>
开发语言·数据结构·c++
小学生的信奥之路11 小时前
力扣1991:找到数组的中间位置(前缀和)
数据结构·算法·leetcode·前缀和·数组
এ᭄画画的北北11 小时前
力扣-102.二叉树的层序遍历
数据结构·算法·leetcode
ccLianLian11 小时前
数据结构·字典树
数据结构·算法
Lu Yao_12 小时前
用golang实现二叉搜索树(BST)
开发语言·数据结构·golang
JeffersonZU13 小时前
【数据结构】2-3-1单链表的定义
数据结构·链表
JeffersonZU13 小时前
【数据结构】1-4算法的空间复杂度
c语言·数据结构·算法