目录
判断题
选择题
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填进去就行
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可能正确
选择排序图示:
15.对一组包含10个元素的非递减有序序列,采用直接插入排序排成非递增序列,其可能的比较次数和移动次数分别是:
A.100, 100
B.54, 63
C.100, 54
D.45, 44
选D,解析:当元素均为逆序时,插入排序执行的比较和交换次数为n*(n-1)/2,但本题可以考虑有两个元素相同的情况,所以移动次数可以比45少1。
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.冒泡排序
本题要求用冒泡排序将一组整数按增序排序。冒泡排序每次从头到尾扫描待排序列,检查相邻两数的顺序,如果顺序不对就交换。请补全下列冒泡排序的代码。
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)
。请完成下列填空。
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;
}
至此,我们完成了排序算法的排序、选择、填空的相关练习,在下一篇文章中我们将进行排序算法编程题的练习。