976
社区成员
发帖
与我相关
我的任务
分享
这是我参加“朝闻道”知识分享大赛的第六十篇文章。
顺序查找:按照数组顺序一个一个的比对查找,找到时返回下标,无法找到时返回最后一个位置,在问题5中的顺序查找中,我们并不是返回最后的位置的。当找到了比k大的元素还未返回值时,我们就对这个元素和其上一个元素分别与k进行比对,得到绝对差值最小的那一个,用于输出最接近的值。查找次数为查找元素与数组元素的比较次数。
//顺序查找
int SequentialSearch(int k, int &comparisons) {
for (int i = 0; i < n; ++i) {
++comparisons;
if (arr[i] == k) {
return i;
} else if (arr[i] > k) {
// 元素不在数组中,返回最接近的元素位置
if (i == 0) {
return i;
} else {
//检查前一个元素是否更加接近
return (k - arr[i-1] <= arr[i] - k) ? i-1 : i;
}
}
}
// 元素不在数组中,返回最后一个位置
return n - 1;
}
插值查找:将值与下标视作一xy坐标轴,确定k的值只需要用求直线坐标的方法确定即可确定pos的值,这样可使得pos的值较大概率的接近,若查找元素不在数组中,需要返回最接近元素,其思路和二分查找一致。查找次数为pos值与数组元素的比较次数。
// 插值查找
int InterpolationSearch(int k, int &comparisons) {
int l = 0, r = n - 1;
while (l <= r && arr[l] <= k && arr[r] >= k) {
if (l == r) {
if (arr[l] == k) return l;
else return -1;
}
// 插值公式
int pos = l + ((double)(r - l) / (arr[r] - arr[l])) * (k - arr[l]);
// 调整搜索范围
comparisons++;
//cout<<"pos:"<<pos<<endl;
if (arr[pos] == k) return pos;
else if (arr[pos] < k) l = pos + 1;
else r = pos - 1;
}
// 元素不在数组中,返回最接近的元素位置
if (r < 0) return l;
else if (l >= n) return r;
else {
// 找到最接近的元素位置
//cout<<"k - arr[l-1]:"<<k - arr[l-1]<<endl;
//cout<<"arr[l] - k:"<<arr[l] - k<<endl;
if(arr[l]>k){
if ( k - arr[l-1] <= arr[l] - k) {
return l-1;
} else {
return l; // 否则返回当前位置 l
}
}else{
if ( k - arr[l] <= arr[l+1] - k) {
return l;
} else {
return l+1; // 否则返回当前位置 l
}
}
}
return -1;
}
蛮力法查找数组中第k个最小元素:在循环中,将数组中找到的最小值赋值为-1,用一个count记录比较次数直到到k就停止循环。最后返回其元素的值即可。
//查找第k个最小元素,蛮力法
int BruteForceKthSmallest(int k, int &comparisons){
int *a=(int*)malloc(n*sizeof(int));
for(int i=0;i<n;i++){
a[i]=arr1[i];
}
int count=0,min=100;
int len =n;
while(count<k){
min=100;
int x=0; //记录最小元素的下标
int i=0;
for(i;i<len;i++){
comparisons++;
if(a[i]<min&&a[i]>=0){
min=a[i];
x=i;
}
}
a[x]=-1; //暂时将已经找到的最小值赋值为-1
count++;
}
return min;
}