查找与排序练习
在散列表中,所谓同义词就是被不同散列函数映射到同一地址的两个元素。
将个元素存入用长度为的数组表示的散列表,则该表的装填因子为。
要从50个键值中找出最大的3个值,选择排序比堆排序快。
内排序要求数据一定要以顺序方式存储。
排序的稳定性是指排序算法中的比较次数保持不变,且算法能够终止。
给定输入序列 {4371, 1323, 6173, 4199, 4344, 9679, 1989} 以及散列函数 。如果用大小为10的散列表,并且用平方探测解决冲突,则输入各项经散列后在表中的下标为:(-1表示相应的插入无法成功)
设有一组关键字 { 29,01, 13,15,56,20,87,27,69,9,10,74 },散列函数为 ,采用平方探测方法解决冲突。试在 0 到 18 的散列地址空间中对该关键字序列构造散列表,则成功查找的平均查找长度为 __
对一组数据{ 2,12,16,88,5,10 }进行排序,若前三趟排序结果如下: 第一趟排序结果:2,12,16,5,10,88 第二趟排序结果:2,12,5,10,16,88 第三趟排序结果:2,5,10,12,16,88 则采用的排序方法可能是:
在内部排序时,若选择了归并排序而没有选择插入排序,则可能的理由是:
归并排序的程序代码更短
归并排序占用的空间更少
归并排序的运行效率更高
本函数的功能是从有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 ) ; 3分;
- 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) ) 3分;
- else
- return Pivot;
- }
本函数的功能是从有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 ) ; 3分;
- 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) ) 3分;
- else
- return Pivot;
- }
由n个正整数构成的集合A{ak}, 将其划分为两个不相交的子集A1,A2, 元素个数分别是n1,n2, A1和A2中的元素之和分别是S1,S2。 设计一个尽可能高效的划分算法,满足|n1-n2|最小,且|S1-S2|最大,返回|S1-S2|的结果。 注意:函数头已经给出,只需要写出函数体。
函数接口定义:
- int Partition(int a[],int n); // 将数组a的整数集合划分成两个不相关子集,使得|n1-n2|最小,且|S1-S2|最大,返回|S1-S2|的结果。
裁判测试程序样例:
- #include<stdio.h>int Partition(int a[],int n);int main(){ int a[60000],n; scanf("%d",&n); for(int i=0;i<n;i++)
- { scanf("%d",&a[i]);
- } printf("%d\n",Partition(a,n));
- }int Partition(int a[],int n){/* 请在这里填写答案,仅写出函数体,不需要写函数头以及“{”,“ }”*/
- //划分整数数组算法}
输入样例:
在这里给出一组输入。例如:
- 6
- 1 9 20 8 100 15
输出样例:
在这里给出相应的输出。例如:
- 117
- int pivotkey,low=0,low0=0,high=n-1,high0=n-1,flag=1,k=n/2,i;
- int s1=0,s2=0;
- while(flag){
- pivotkey=a[low];
- while(low<high){
- while(low<high && a[high]>=pivotkey){
- --high;
- }
- if(low!=high){
- a[low]=a[high];
- }
- while(low<high && a[low]<pivotkey){
- ++low;
- }
- if(low!=high){
- a[high]=a[low];
- }
- }
- a[low]=pivotkey;
- if(low==k-1) flag=0;
- else{
- if(low<k-1){
- low0=++low;
- high=high0;
- }
- else{
- high0=--high;
- low=low0;
- }
- }
- }
- for(i=0;i<k;i++){
- s1+=a[i];
- }
- for(i=k;i<n;i++){
- s2+=a[i];
- }
- return s2-s1;
本题要求实现二分查找算法。
函数接口定义:
- Position BinarySearch( List L, ElementType X );
其中List
结构定义如下:
- typedef int Position;typedef struct LNode *List;struct LNode {
- ElementType Data[MAXSIZE];
- Position Last; /* 保存线性表中最后一个元素的位置 */};
L
是用户传入的一个线性表,其中ElementType
元素可以通过、、进行比较,并且题目保证传入的数据是递增有序的。函数BinarySearch
要查找X
在Data
中的位置,即数组下标(注意:元素从下标1开始存储)。找到则返回下标,否则返回一个特殊的失败标记NotFound
。
裁判测试程序样例:
- #include <stdio.h>#include <stdlib.h>#define MAXSIZE 10#define NotFound 0typedef int ElementType;typedef int Position;typedef struct LNode *List;struct LNode {
- ElementType Data[MAXSIZE];
- Position Last; /* 保存线性表中最后一个元素的位置 */};List ReadInput(); /* 裁判实现,细节不表。元素从下标1开始存储 */Position BinarySearch( List L, ElementType X );int main(){
- List L;
- ElementType X;
- Position P;
- L = ReadInput(); scanf("%d", &X);
- P = BinarySearch( L, X ); printf("%d\n", P); return 0;
- }/* 你的代码将被嵌在这里 */
输入样例1:
- 5
- 12 31 55 89 101
- 31
输出样例1:
- 2
输入样例2:
- 326 78 23331
输出样例2:
- 0
鸣谢宁波大学 Eyre-lemon-郎俊杰 同学修正原题!
- Position BinarySearch(List L, ElementType X)
- {
- ElementType left = 1;
- ElementType right = L->Last;
- ElementType mid;
- while(left<=right) {
- mid = (left+right)/2;
- if(X == L->Data[mid]) {
- return (mid);
- } else if(X < L->Data[mid]) {
- right = mid-1;
- } else {
- left = mid+1;
- }
- }
- return NotFound;
- }