查找与排序练习
在散列表中,所谓同义词就是被不同散列函数映射到同一地址的两个元素。
将个元素存入用长度为的数组表示的散列表,则该表的装填因子为。
要从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; }