静态查找之顺序查找、折半查找、索引查找、中位数

静态查找表

DS静态查找之顺序查找

题目描述

给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始

要求使用带哨兵的顺序查找算法

输入

第一行输入n,表示队列有n个数据
第二行输入n个数据,都是正整数,用空格隔开
第三行输入t,表示有t个要查找的数值
第四行起,输入t个数值,输入t行

输出

每行输出一个要查找的数值在队列的位置,如果查找不成功,输出字符串error

样例查看模式
正常显示
查看格式

8
33 66 22 88 11 27 44 55
3
22
11
99

输出样例

3
5
error
思路如下:

顺序查找,在数组arr[0]处设置哨兵,从数组下标1开始查找,并记录查找次数

AC代码如下:

#include <iostream>

using namespace std;
const int N = 100010;
int arr[N] = {0};
int len, t, num;

int find(){
    for(int i = 1;i <= len;i++){
        if(arr[i] == arr[0])
            return i;
    }
    return 0;
}

int main() {
    cin >> len;
    for (int i = 1; i <= len; i++) {
        cin >> arr[i];
    }
    cin >> t;
    while (t--) {
        cin >> arr[0];
        int times = find();
        if(times) cout << times << endl;
        else cout <<"error" << endl;
    }
    return 0;
}

【6分】 DS静态查找之折半查找

题目描述

给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始

要求使用折半查找算法

输入

第一行输入n,表示队列有n个数据
第二行输入n个数据,都是正整数,用空格隔开
第三行输入t,表示有t个要查找的数值
第四行起,输入t个数值,输入t行

输出

每行输出一个要查找的数值在队列的位置,如果查找不成功,输出字符串error

样例查看如下
输入

8
11 22 33 44 55 66 77 88
3
22
88
99

输出:

2
8
error

AC代码思路,递归返回

#include "iostream"

using namespace std;
const int N = 10;
int arr[N] = {0};
int len, t;

/*
 * 递归查找
 * */
void findIndex(int low, int high) {
    if (low > high) {// 结束条件
        cout << "error" << endl;
        return;
    }

    int mid = (low + high) / 2;
    if (arr[mid] > arr[0]) high = mid - 1;
    else if (arr[mid] < arr[0]) low = mid + 1;
    else if (arr[mid] == arr[0]) {
        cout << mid << endl;
        return;
    }
    findIndex(low, high);
}

int main() {
    cin >> len;
    for (int i = 1; i <= len; i++) cin >> arr[i];
    cin >> t;
    while (t--) {
        cin >> arr[0];  // arr[0]存放需要查找的数据
        findIndex(1,len);
    }
    return 0;
}

【6分】 DS静态查找之顺序索引查找

题目描述

给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始

要求使用顺序索引查找算法,其中索引表查找和块内查找都采用不带哨兵、从头开始的顺序查找方法。

输入

第一行输入n,表示主表有n个数据
第二行输入n个数据,都是正整数,用空格隔开
第三行输入k,表示主表划分为k个块,k也是索引表的长度
第四行输入k个数据,表示索引表中每个块的最大值
第五行输入t,表示有t个要查找的数值
第六行起,输入t个数值,输入t行

输出

每行输出一个要查找的数值在队列的位置和查找次数,数据之间用短划线隔开,如果查找不成功,输出字符串error

样例如下

输入:

18
22 12 13 8 9 20 33 42 44 38 24 48 60 58 74 57 86 53
3
22 48 86
6
13
5
48
40
53
90

输出:

3-4
error
12-8
error
18-9
error

AC思路如下:建立结构体设置包含每个分块的最大值、开始位置;输入数组后(从1位置开始存储)初始化索引表数组

#include "iostream"

using namespace std;

/*
 * 索引顺序查找表
 * 表内无序 块间有序
 * */
const int N = 10010;
int arr[N] = {0}, len;
int k;  // 划分为k个块
int t;  // 查找t个数

struct IndexType {
    int maxKey = 0;
    int startPos = 0;
};

void Find(IndexType *indexType, int k) {
    int times = 0;
    bool flag = false;
    int i = 1;
    for (; i < k + 1; i++) {
        if (indexType[i].maxKey >= arr[0]) {
            flag = true;    // 找到区间范围限制 返回
            times++;
            break;
        }
        times++;
    }
    if (!flag) {        // 没有找到
        cout << "error" << endl;
        return;
    }
    int index = 0;
    if (i == k) index = len;
    else index = indexType[i + 1].startPos - 1;
    for (int j = indexType[i].startPos; j <= index; j++) {
        times++;
        if (arr[j] == arr[0]) {
            cout << j << "-" << times << endl;
            return;
        }
    }
    cout << "error" << endl;
}

int main() {
    cin >> len;
    for (int i = 1; i <= len; i++) cin >> arr[i];

    cin >> k;   // 划分为k个块 并输入k个块的最大索引值
    // 为了统一下标从1开始  所以多开了一个空间
    IndexType *indexType = new IndexType[k + 1];
    int j = 1;
    for (int i = 1; i <= k; i++) {
        cin >> indexType[i].maxKey;
        indexType[i].startPos = j;
        while (indexType[i].maxKey >= arr[j] && j <= len) j++;
    }
    cin >> t;
    while (t--) {
        cin >> arr[0];  // 存放需要查找的数据
        Find(indexType, k);
    }
    delete[]indexType;
}

【6分】两个有序序列的中位数

题目描述

已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A
​0
​​ ,A
​1
​​ ,⋯,A
​N−1
​​ 的中位数指A
​(N−1)/2
​​ 的值,即第⌊(N+1)/2⌋个数(A
​0
​​ 为第1个数)。

只需考虑中位数唯一的情况

输入

输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。

输出

在一行中输出两个输入序列的并集序列的中位数.
样例如下:
输入

5
1 3 5 7 9
2 3 4 5 6

输出

4

题目简单,无思路

#include "iostream"

using namespace std;

const int N = 10010;
int arr_1[N] = {0};
int arr_2[N] = {0};
int arr[N] = {0};
int len;

int main(){
    cin >> len;
    for(int i = 0;i < len;i++) cin >> arr_1[i];
    for(int i =0;i < len;i++) cin >> arr_2[i];
    int i = 0,j = 0,idx=0;
    for(;idx < (2*len + 1)/2;idx ++){
        if(i < len && j < len && arr_1[i] <= arr_2[j]){
            arr[idx] = arr_1[i];
            i++;
        }else if(i < len && j < len && arr_2[j] < arr_1[i]){
            arr[idx] = arr_2[j];
            j++;
        }else if(i >= len && j < len){
            arr[idx] = arr_2[j];
            j++;
        }else if(j >= len && i < len){
            arr[idx] = arr_1[i];
            i++;
        }
    }cout << arr[idx-1] << endl;
}
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值