2-4 折半查找

2-4 折半查找

  • 分数:10
  • 作者:陈越
  • 单位:浙江大学

题目描述

请编写程序,实现有序顺序表的折半查找算法。

输入格式

  1. 输入首先给出一个正整数 n(≤10⁵),表示顺序表的元素个数;
  2. 随后一行按升序给出 n 个不超过 10⁸ 的正整数,为顺序表中的元素(题目保证无重复元素);
  3. 最后一行给出若干正整数,为需要查找的元素,最后以 -1 结尾(-1 不需要查找);
  4. 同行数字间以空格分隔。

输出格式

在一行中输出每个待查找元素在顺序表中的位序(位序从 1 开始):

  • 若元素在表中,输出其位序;
  • 若元素不在表中,输出 0
  • 每个数字后面跟一个空格(包括最后一个输出项)。

输入输出样例

输入样例

9
1 2 3 4 5 6 7 8 9
1 5 4 9 10 -1

输出样例

1 5 4 9 0 

代码限制

  • 代码长度限制:16 KB
  • 时间限制:400 ms
  • 内存限制:64 MB
  • 栈限制:8192 KB

解析

#include<stdio.h>
#include<stdlib.h>
// 定义一个顺序表
/* ==================================================================*/
#define RATIO 2
typedef int SeqData_t;
typedef struct{
    SeqData_t *data;
    int len;    // 表长
    int capacity;    // 表容量
}SeqTable;
// 创建一个顺序表
SeqTable *createSeqTable(int n){
    if(n <= 0) return NULL;
    SeqTable *table = malloc(sizeof(SeqTable)); if(!table) return NULL;
    table->data = malloc(sizeof(SeqData_t) * n);
    if(!table->data){
        free(table);
        return NULL;
    }
    table->len = 0;    // 初始化表长
    table->capacity = n;    // 初始化表容量
    return table;
}
void releaseSeqTable(SeqTable *table){
    if(table){
        if(table->data){
            free(table->data);
        }
        table->len = 0;
        table->capacity = 0;
        free(table);
    }
}
void pushBack(SeqTable *table, SeqData_t data){
    if(!table) return;
    if(table->len >= table->capacity){
        // 扩容
        SeqData_t *temp = realloc(table->data, sizeof(SeqData_t) * table->capacity *RATIO);
        if(!temp) return;
        table->data = temp;
        table->capacity *= RATIO;
    }
    // 插入数据
    table->data[table->len] = data;
    table->len++;    // 表长➕1
}
// 二分查找,未找到或失败返回-1
int binarySearch(SeqTable *seqTable, SeqData_t e){
    if(!seqTable) return -1;
    int left = 0, right = seqTable->len - 1, mid;
    while(left <= right){
        mid = left + (right - left) / 2;    // 防止溢出
        if(seqTable->data[mid] < e){
            // 往右边找
            left = mid + 1;
        }
        else if(seqTable->data[mid] > e){
            // 往左边找
            right = mid - 1;
        }
        else{
            return mid + 1;    // 找到了,返回该元素位序
        }
    }
    return -1;    // 遍历完顺序表依然未返回说明待查找元素不存在
}
int main(){
    int n; scanf("%d", &n);
    SeqTable *seqTable = createSeqTable(n);
    SeqData_t data;    // 暂存输入元素
    for(int i = 0; i < n; i++){
        scanf("%d", &data);
        pushBack(seqTable, data);
    }
    int pos;    // 存待查找元素位序
    while(1){
        scanf("%d", &data);
        if(data == -1) break;
        printf("%d ", (pos = binarySearch(seqTable, data)) == -1 ? 0 : pos);
    }
    releaseSeqTable(seqTable);
    return 0;
}
折半查找(Binary Search),也称为二分查找,是一种在有序数组中查找特定元素的高效算法。其基本思想是将数组分成两部分,然后根据目标值与中间元素的大小关系,确定目标值可能存在的区间,然后继续在该区间内进行查找,直到找到目标值或确定目标值不存在。 ### PTA平台折半查找题目示例及解答 #### 题目描述 在一个有序数组中查找一个特定元素,如果找到则返回其索引,否则返回 -1。 #### 代码实现(Python) ```python def binary_search(arr, target): left, right = 0, len(arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] < target: left = mid + 1 else: right = mid - 1 return -1 # 测试代码 arr = [1, 3, 5, 7, 9, 11, 13] target = 7 result = binary_search(arr, target) print(result) ``` #### 代码解释 1. **初始化左右指针**:`left` 指向数组的起始位置,`right` 指向数组的末尾位置。 2. **进入循环**:只要 `left` 小于等于 `right`,就继续循环。 3. **计算中间位置**:`mid = (left + right) // 2`。 4. **比较中间元素与目标值**: - 如果 `arr[mid]` 等于 `target`,则返回 `mid`。 - 如果 `arr[mid]` 小于 `target`,则将 `left` 更新为 `mid + 1`。 - 如果 `arr[mid]` 大于 `target`,则将 `right` 更新为 `mid - 1`。 5. **如果循环结束仍未找到目标值**:返回 -1。 ### PTA平台折半查找使用指南 #### 理解题目要求 在PTA平台上,首先要仔细阅读题目描述,明确题目要求,例如查找的数组是否有序、是否需要处理重复元素等。 #### 编写代码 根据题目要求编写折半查找的代码,注意边界条件的处理,例如数组为空、目标值不在数组中等情况。 #### 测试代码 在提交代码之前,使用一些测试用例对代码进行测试,确保代码的正确性。 #### 提交代码 将编写好的代码复制到PTA平台的代码编辑器中,然后提交代码进行评测。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值