数据结构与算法--分块查找--pair类型

分块查找(也称为索引顺序查找)是一种在有序数组中进行查找的方法,它通过将数组分成若干块,并在每块中使用一个索引来加速查找过程。这种方法适用于数组太大而无法一次性加载到内存中,或者数组太大而不适合使用二分查找的情况。

### 分块查找的步骤:

1. **确定块大小**:首先,确定每个块包含多少元素。块的大小应该根据内存容量和查找效率来确定。

2. **创建索引**:为每个块创建一个索引,索引中包含每个块中的最大值和块的起始位置。

3. **确定目标块**:通过比较待查找的值与索引中的值,确定待查找的值可能位于哪个块中。

4. **在块内查找**:一旦确定了目标块,就在该块内进行顺序查找。

### 分块查找的优缺点:

**优点**:
- **减少比较次数**:对于大型数据集,分块查找可以显著减少比较次数,因为它首先在索引中进行查找,而不是直接在数据集中查找。
- **适用于外部存储**:当数据太大而无法完全加载到内存中时,分块查找可以有效地利用外部存储。

**缺点**:
- **额外的存储空间**:需要额外的空间来存储索引。
- **效率依赖于块大小**:块的大小对查找效率有很大影响。如果块太小,可能会有太多的块和索引需要维护;如果块太大,可能会减少查找效率。
- **块内顺序查找**:一旦确定了目标块,仍然需要在块内进行顺序查找,这可能会增加查找时间。

### 示例:

假设有一个有序数组,我们将其分成若干块,每块包含3个元素:

```
数组:[10, 12, 15, 20, 22, 25, 30, 31, 35, 40]
块1:[10, 12, 15]   索引:[15, 0]
块2:[20, 22, 25]   索引:[25, 3]
块3:[30, 31, 35]   索引:[35, 6]
块4:[40]           索引:[40, 9]
```

现在,如果我们想要查找值25,我们首先查看索引,发现25在第二块中(索引值为25,起始位置为3)。然后,我们直接跳到数组的第三个位置开始查找,这样就大大减少了查找所需的比较次数。

分块查找是一种有效的查找方法,特别是在处理大型数据集时,它可以显著提高查找效率。然而,它也需要仔细设计块的大小和索引结构,以确保最佳性能。

在C++中,`pair` 是一个非常有用的模板类,它包含两个元素,通常用于存储一对相关联的值。`pair` 定义在头文件 `<utility>` 中,并且是C++标准库的一部分。

### 基本用法

`pair` 可以存储任何类型的数据,只要这些类型是可以复制的。你可以使用 `pair` 来存储两个相关联的值,例如,一个键和它的值,或者两个相关的计算结果。

#include <iostream>
#include <utility> // 包含pair的定义

int main() {
    std::pair<int, double> p = {1, 3.14};
    std::cout << "First: " << p.first << ", Second: " << p.second << std::endl;
    return 0;
}

在这个例子中,`p` 是一个 `pair`,包含一个整数和一个双精度浮点数。

### 成员变量

- `first`:用于访问 `pair` 中的第一个元素。
- `second`:用于访问 `pair` 中的第二个元素。

### 构造函数

`pair` 提供了多种构造函数,允许你以不同的方式初始化 `pair` 对象。例如,你可以在创建 `pair` 时直接指定两个元素:

std::pair<int, std::string> p = {10, "Hello"};

### 用途

`pair` 在标准库中广泛使用,特别是在容器如 `std::map` 和 `std::multimap` 中,这些容器的元素类型通常是 `std::pair<const Key, Value>`。

### 排序和比较

`pair` 支持默认的比较操作,首先比较第一个元素,如果第一个元素相等,则比较第二个元素。这使得 `pair` 可以直接用于需要排序的容器中,如 `std::vector` 或 `std::set`。

#include <algorithm>
#include <vector>
#include <utility>

int main() {
    std::vector<std::pair<int, std::string>> vec = {{1, "one"}, {3, "three"}, {2, "two"}};

    std::sort(vec.begin(), vec.end()); // 默认按第一个元素排序

    for (const auto& p : vec) {
        std::cout << p.first << ": " << p.second << std::endl;
    }

    return 0;
}

在这个例子中,`vec` 是一个包含 `pair` 的向量,`std::sort` 默认按照 `pair` 的第一个元素进行排序。

`pair` 是C++中一个非常灵活和强大的工具,用于处理成对的数据。

分块排序ai代码实现:


#include <iostream>
#include <vector>

using namespace std;

// 构建索引
vector<pair<int, int>> buildIndex(const vector<int>& data, int blockSize) {
    int n = data.size();
    vector<pair<int, int>> index;
    for (int i = 0; i < n; i += blockSize) {
        int maxVal = data[i];
        for (int j = i + 1; j < i + blockSize && j < n; ++j) {
            if (data[j] > maxVal) {
                maxVal = data[j];
            }
        }
        index.push_back({maxVal, i});
    }
    return index;
}

// 分块查找
int blockSearch(const vector<int>& data, const vector<pair<int, int>>& index, int target) {
    int blockIndex = 0;
    // 在索引中查找可能包含目标值的块
    while (blockIndex < index.size() && target > index[blockIndex].first) {
        ++blockIndex;
    }
    // 在选定的块内进行顺序查找
    int start = index[blockIndex].second;
    for (int i = start; i < start + blockSize && i < data.size(); ++i) {
        if (data[i] == target) {
            return i; // 找到目标值,返回索引
        }
    }
    return -1; // 未找到目标值
}

int main() {
    vector<int> data = {10, 12, 15, 20, 22, 25, 30, 31, 35, 40};
    int blockSize = 3;
    int target = 25;

    // 构建索引
    vector<pair<int, int>> index = buildIndex(data, blockSize);

    // 打印索引
    cout << "Index:" << endl;
    for (const auto& entry : index) {
        cout << "(" << entry.first << ", " << entry.second << ")" << endl;
    }

    // 进行查找
    int result = blockSearch(data, index, target);
    if (result != -1) {
        cout << "Element found at index: " << result << endl;
    } else {
        cout << "Element not found." << endl;
    }

    return 0;
}

手写代码实现:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <Windows.h> // 包含头文件
using namespace std;

#include <utility> // 包含pair的定义
int size = 10; //每块大小
int data_size = 100; //数组总大小
int max = 100; //随机生成数最大值



bool compare(int a, int b) { return a > b; }

//创建索引
vector<pair<int, int>> creatSY(const vector<int>& data, int size) {

	vector<pair<int, int>> index;
	int max_size = data.size() / size;
	if (data.size() % size > 0) max_size++;


	for (int i = 0; i < max_size; i++) {
		pair<int, int> temp;
		temp.first = i * size;
		if (data.size() > (i+1) * size) {

			temp.second = data[(i+1) * size -1 ];
		}
		else temp.second = data[data.size()-1];
		index.push_back(temp);
	}
	return index;
}

int search(const vector<pair<int, int>>& p, const vector<int>& data,int target) {
	for (int i = 0; i < p.size(); i++) {
		if (p[i].second >= target) {
			bool check = false;
			for (int j = p[i].first; j < p[i].first+::size; j++) {
				if (data[j] == target) {
					check = true;
					return j;
				}
			}
			if (check == false) {
				return -1;
			}
		}
	}
	return -1;
}

int main() {

	srand(time(0));
	int time = 0;

	while (1) {
		//分段查找----适用于数据量中等,同时可以减少比较次数
	//确定块大小
	//确定目标块
	//在块内查找


		vector<int>data(data_size);
		for (int i = 0; i < data_size; i++) {
			data[i] = rand() % ::max;
			//data[i] = i;  //为了确保能找到目标,不使用随机生成
		}
		//sort(data.begin(), data.end(),compare);
		sort(data.begin(), data.end());
		for (int i = 0; i < data.size(); i++)cout << data[i] << ' ';
		cout << endl;

		vector<pair<int, int>> p = creatSY(data, ::size);
		for (const auto& entry : p) {
			cout << "index : " << entry.first << " value : " << entry.second << endl;
		}

		int target = rand() % data_size;
		cout << "target : " << target << endl;

		//分组查找
		int result = search(p, data, target);

		if (result == -1) cout << "未找到目标" << endl;
		else cout << "找到目标 index:" << result << endl;


		Sleep(10);

		time++;
		if (time > 500) break;

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值