8种经典查找算法完整C++实现

3 阅读15分钟

以下是8种经典查找算法的完整C++实现,包括详细注释、时间/空间复杂度分析和测试代码。

完整实现代码

/**
 * 8种经典查找算法完整C++实现
 * 编译: g++ -std=c++11 -O2 search_algorithms.cpp -o search
 */

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <map>
#include <unordered_map>
#include <memory>
#include <iomanip>
using namespace std;

// ==================== 工具函数 ====================
template<typename T>
void printArray(const vector<T>& arr, const string& name = "") {
    if (!name.empty()) cout << name << ": ";
    for (const auto& val : arr) cout << val << " ";
    cout << endl;
}

// 生成有序数组用于查找
vector<int> generateSortedArray(int n) {
    vector<int> arr(n);
    for (int i = 0; i < n; i++) {
        arr[i] = i * 2;  // 偶数序列,确保间隔
    }
    return arr;
}

// ==================== 1. 顺序查找 ====================
/**
 * 时间复杂度: O(n)
 * 空间复杂度: O(1)
 * 适用: 无序数组/链表
 */
template<typename T>
int sequentialSearch(const vector<T>& arr, const T& target) {
    for (size_t i = 0; i < arr.size(); i++) {
        if (arr[i] == target) {
            return static_cast<int>(i);
        }
    }
    return -1;  // 未找到
}

// 带哨兵的顺序查找(减少比较次数)
template<typename T>
int sequentialSearchWithSentinel(vector<T>& arr, const T& target) {
    if (arr.empty()) return -1;
    
    // 将目标值放入末尾作为哨兵
    T last = arr.back();
    arr.back() = target;
    
    size_t i = 0;
    while (arr[i] != target) {
        i++;
    }
    
    // 恢复原数组
    arr.back() = last;
    
    if (i < arr.size() - 1 || arr.back() == target) {
        return static_cast<int>(i);
    }
    return -1;
}

// ==================== 2. 二分查找 ====================
/**
 * 时间复杂度: O(log n)
 * 空间复杂度: O(1) 迭代, O(log n) 递归
 * 适用: 有序数组
 */

// 迭代版本
template<typename T>
int binarySearchIterative(const vector<T>& arr, const T& target) {
    int left = 0;
    int right = static_cast<int>(arr.size()) - 1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;  // 避免溢出
        
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}

// 递归版本
template<typename T>
int binarySearchRecursiveHelper(const vector<T>& arr, const T& target, 
                               int left, int right) {
    if (left > right) return -1;
    
    int mid = left + (right - left) / 2;
    
    if (arr[mid] == target) {
        return mid;
    } else if (arr[mid] < target) {
        return binarySearchRecursiveHelper(arr, target, mid + 1, right);
    } else {
        return binarySearchRecursiveHelper(arr, target, left, mid - 1);
    }
}

template<typename T>
int binarySearchRecursive(const vector<T>& arr, const T& target) {
    return binarySearchRecursiveHelper(arr, target, 0, static_cast<int>(arr.size()) - 1);
}

// 查找第一个等于target的位置
template<typename T>
int binarySearchFirst(const vector<T>& arr, const T& target) {
    int left = 0;
    int right = static_cast<int>(arr.size()) - 1;
    int result = -1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (arr[mid] == target) {
            result = mid;
            right = mid - 1;  // 继续在左半部分查找
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return result;
}

// 查找最后一个等于target的位置
template<typename T>
int binarySearchLast(const vector<T>& arr, const T& target) {
    int left = 0;
    int right = static_cast<int>(arr.size()) - 1;
    int result = -1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (arr[mid] == target) {
            result = mid;
            left = mid + 1;  // 继续在右半部分查找
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return result;
}

// 查找第一个大于等于target的位置
template<typename T>
int binarySearchLowerBound(const vector<T>& arr, const T& target) {
    int left = 0;
    int right = static_cast<int>(arr.size()) - 1;
    int result = static_cast<int>(arr.size());  // 如果没有找到,返回末尾
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (arr[mid] >= target) {
            result = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return result;
}

// 查找第一个大于target的位置
template<typename T>
int binarySearchUpperBound(const vector<T>& arr, const T& target) {
    int left = 0;
    int right = static_cast<int>(arr.size()) - 1;
    int result = static_cast<int>(arr.size());  // 如果没有找到,返回末尾
    
    while (left <= right) {
        int mid = left + (right - left) / 2;
        
        if (arr[mid] > target) {
            result = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return result;
}

// ==================== 3. 插值查找 ====================
/**
 * 时间复杂度: O(log log n) 平均, O(n) 最坏
 * 空间复杂度: O(1)
 * 适用: 均匀分布的有序数组
 */
template<typename T>
int interpolationSearch(const vector<T>& arr, const T& target) {
    int left = 0;
    int right = static_cast<int>(arr.size()) - 1;
    
    // 确保目标值在数组范围内
    if (target < arr[left] || target > arr[right]) {
        return -1;
    }
    
    while (left <= right && target >= arr[left] && target <= arr[right]) {
        if (left == right) {
            return (arr[left] == target) ? left : -1;
        }
        
        // 计算插值位置
        int pos = left + static_cast<int>((static_cast<double>(right - left) / 
                  (arr[right] - arr[left])) * (target - arr[left]));
        
        // 防止越界
        pos = max(left, min(pos, right));
        
        if (arr[pos] == target) {
            return pos;
        } else if (arr[pos] < target) {
            left = pos + 1;
        } else {
            right = pos - 1;
        }
    }
    return -1;
}

// ==================== 4. 斐波那契查找 ====================
/**
 * 时间复杂度: O(log n)
 * 空间复杂度: O(1)
 * 适用: 有序数组,避免除法运算
 */
vector<int> generateFibonacci(int n) {
    vector<int> fib;
    if (n <= 0) return fib;
    
    fib.push_back(0);
    if (n == 1) return fib;
    
    fib.push_back(1);
    for (int i = 2; i < n; i++) {
        fib.push_back(fib[i-1] + fib[i-2]);
    }
    return fib;
}

template<typename T>
int fibonacciSearch(const vector<T>& arr, const T& target) {
    int n = static_cast<int>(arr.size());
    
    // 生成斐波那契数列
    vector<int> fib = generateFibonacci(20);  // 20足够覆盖大多数情况
    
    // 找到第一个大于等于n的斐波那契数
    int k = 0;
    while (fib[k] < n) {
        k++;
    }
    
    // 扩展数组到fib[k]长度
    vector<T> temp = arr;
    for (int i = n; i < fib[k]; i++) {
        temp.push_back(arr[n-1]);  // 用最后一个元素填充
    }
    
    int left = 0;
    int right = fib[k] - 1;
    
    while (left <= right) {
        int mid = left + fib[k-1] - 1;  // 黄金分割点
        
        if (mid >= n) mid = n - 1;  // 防止越界
        
        if (temp[mid] == target) {
            return (mid < n) ? mid : n-1;  // 如果找到的是填充值,返回最后一个元素索引
        } else if (temp[mid] < target) {
            left = mid + 1;
            k -= 2;  // 在右侧查找
        } else {
            right = mid - 1;
            k -= 1;  // 在左侧查找
        }
    }
    
    return -1;
}

// ==================== 5. 哈希查找 ====================
/**
 * 时间复杂度: O(1) 平均, O(n) 最坏
 * 空间复杂度: O(n)
 * 适用: 快速查找,不要求有序
 */

// 简单哈希表实现(链地址法解决冲突)
class SimpleHashTable {
private:
    struct HashNode {
        int key;
        int value;
        HashNode* next;
        
        HashNode(int k, int v) : key(k), value(v), next(nullptr) {}
    };
    
    vector<HashNode*> table;
    int capacity;
    int size;
    
    // 简单哈希函数
    int hashFunction(int key) {
        return key % capacity;
    }
    
public:
    SimpleHashTable(int cap = 100) : capacity(cap), size(0) {
        table.resize(capacity, nullptr);
    }
    
    ~SimpleHashTable() {
        for (int i = 0; i < capacity; i++) {
            HashNode* node = table[i];
            while (node) {
                HashNode* temp = node;
                node = node->next;
                delete temp;
            }
        }
    }
    
    // 插入键值对
    void insert(int key, int value) {
        int index = hashFunction(key);
        HashNode* node = table[index];
        
        // 检查是否已存在
        while (node) {
            if (node->key == key) {
                node->value = value;  // 更新值
                return;
            }
            node = node->next;
        }
        
        // 插入到链表头部
        HashNode* newNode = new HashNode(key, value);
        newNode->next = table[index];
        table[index] = newNode;
        size++;
    }
    
    // 查找键
    int search(int key) {
        int index = hashFunction(key);
        HashNode* node = table[index];
        
        while (node) {
            if (node->key == key) {
                return node->value;
            }
            node = node->next;
        }
        
        return -1;  // 未找到
    }
    
    // 删除键
    bool remove(int key) {
        int index = hashFunction(key);
        HashNode* node = table[index];
        HashNode* prev = nullptr;
        
        while (node) {
            if (node->key == key) {
                if (prev) {
                    prev->next = node->next;
                } else {
                    table[index] = node->next;
                }
                delete node;
                size--;
                return true;
            }
            prev = node;
            node = node->next;
        }
        
        return false;
    }
    
    int getSize() const { return size; }
    int getCapacity() const { return capacity; }
    
    void print() {
        for (int i = 0; i < capacity; i++) {
            cout << "Bucket " << i << ": ";
            HashNode* node = table[i];
            while (node) {
                cout << "(" << node->key << "," << node->value << ") ";
                node = node->next;
            }
            cout << endl;
        }
    }
};

// 布隆过滤器(概率性数据结构)
class BloomFilter {
private:
    vector<bool> bits;
    int size;
    vector<int> seeds;  // 不同哈希函数的种子
    
    // 简单哈希函数
    int hash(const string& key, int seed) {
        int hash = 0;
        for (char c : key) {
            hash = seed * hash + c;
        }
        return abs(hash) % size;
    }
    
public:
    BloomFilter(int n, int numHashes = 3) : size(n) {
        bits.resize(n, false);
        // 使用不同的种子创建多个哈希函数
        for (int i = 0; i < numHashes; i++) {
            seeds.push_back(131 + i * 100);  // 常见质数
        }
    }
    
    void insert(const string& key) {
        for (int seed : seeds) {
            int index = hash(key, seed);
            bits[index] = true;
        }
    }
    
    bool contains(const string& key) {
        for (int seed : seeds) {
            int index = hash(key, seed);
            if (!bits[index]) {
                return false;  // 一定不存在
            }
        }
        return true;  // 可能存在(有假阳性)
    }
    
    void printStats() {
        int count = 0;
        for (bool bit : bits) {
            if (bit) count++;
        }
        cout << "Bloom Filter: " << count << "/" << size << " bits set" << endl;
    }
};

// ==================== 6. 二叉搜索树查找 ====================
/**
 * 时间复杂度: O(log n) 平均, O(n) 最坏
 * 空间复杂度: O(n)
 * 适用: 动态查找表
 */

class BinarySearchTree {
private:
    struct TreeNode {
        int key;
        int value;
        TreeNode* left;
        TreeNode* right;
        
        TreeNode(int k, int v) : key(k), value(v), left(nullptr), right(nullptr) {}
    };
    
    TreeNode* root;
    int size;
    
    // 插入辅助函数
    TreeNode* insertHelper(TreeNode* node, int key, int value) {
        if (!node) {
            size++;
            return new TreeNode(key, value);
        }
        
        if (key < node->key) {
            node->left = insertHelper(node->left, key, value);
        } else if (key > node->key) {
            node->right = insertHelper(node->right, key, value);
        } else {
            node->value = value;  // 更新值
        }
        
        return node;
    }
    
    // 查找辅助函数
    TreeNode* searchHelper(TreeNode* node, int key) {
        if (!node || node->key == key) {
            return node;
        }
        
        if (key < node->key) {
            return searchHelper(node->left, key);
        } else {
            return searchHelper(node->right, key);
        }
    }
    
    // 中序遍历辅助函数
    void inorderHelper(TreeNode* node, vector<pair<int, int>>& result) {
        if (!node) return;
        inorderHelper(node->left, result);
        result.push_back({node->key, node->value});
        inorderHelper(node->right, result);
    }
    
    // 删除辅助函数
    TreeNode* deleteHelper(TreeNode* node, int key) {
        if (!node) return nullptr;
        
        if (key < node->key) {
            node->left = deleteHelper(node->left, key);
        } else if (key > node->key) {
            node->right = deleteHelper(node->right, key);
        } else {
            // 找到要删除的节点
            if (!node->left) {
                TreeNode* temp = node->right;
                delete node;
                size--;
                return temp;
            } else if (!node->right) {
                TreeNode* temp = node->left;
                delete node;
                size--;
                return temp;
            } else {
                // 有两个子节点,找到右子树的最小节点
                TreeNode* minNode = findMin(node->right);
                node->key = minNode->key;
                node->value = minNode->value;
                node->right = deleteHelper(node->right, minNode->key);
            }
        }
        return node;
    }
    
    TreeNode* findMin(TreeNode* node) {
        while (node && node->left) {
            node = node->left;
        }
        return node;
    }
    
    // 销毁树
    void destroyTree(TreeNode* node) {
        if (!node) return;
        destroyTree(node->left);
        destroyTree(node->right);
        delete node;
    }
    
public:
    BinarySearchTree() : root(nullptr), size(0) {}
    ~BinarySearchTree() { destroyTree(root); }
    
    void insert(int key, int value) {
        root = insertHelper(root, key, value);
    }
    
    int search(int key) {
        TreeNode* node = searchHelper(root, key);
        return node ? node->value : -1;
    }
    
    bool remove(int key) {
        int oldSize = size;
        root = deleteHelper(root, key);
        return size < oldSize;
    }
    
    vector<pair<int, int>> inorderTraversal() {
        vector<pair<int, int>> result;
        inorderHelper(root, result);
        return result;
    }
    
    int getSize() const { return size; }
    int getHeight() { return getHeightHelper(root); }
    
    int getHeightHelper(TreeNode* node) {
        if (!node) return 0;
        return 1 + max(getHeightHelper(node->left), getHeightHelper(node->right));
    }
    
    void printTree() {
        cout << "Binary Search Tree (size: " << size << "):" << endl;
        vector<pair<int, int>> items = inorderTraversal();
        for (auto& item : items) {
            cout << "(" << item.first << "," << item.second << ") ";
        }
        cout << endl;
    }
};

// ==================== 7. 平衡树查找(AVL树) ====================
/**
 * 时间复杂度: O(log n)
 * 空间复杂度: O(n)
 * 适用: 需要频繁插入删除的动态查找表
 */

class AVLTree {
private:
    struct AVLNode {
        int key;
        int value;
        int height;
        AVLNode* left;
        AVLNode* right;
        
        AVLNode(int k, int v) : key(k), value(v), height(1), left(nullptr), right(nullptr) {}
    };
    
    AVLNode* root;
    int size;
    
    // 获取节点高度
    int getHeight(AVLNode* node) {
        return node ? node->height : 0;
    }
    
    // 获取平衡因子
    int getBalance(AVLNode* node) {
        return node ? getHeight(node->left) - getHeight(node->right) : 0;
    }
    
    // 右旋
    AVLNode* rightRotate(AVLNode* y) {
        AVLNode* x = y->left;
        AVLNode* T2 = x->right;
        
        // 旋转
        x->right = y;
        y->left = T2;
        
        // 更新高度
        y->height = 1 + max(getHeight(y->left), getHeight(y->right));
        x->height = 1 + max(getHeight(x->left), getHeight(x->right));
        
        return x;
    }
    
    // 左旋
    AVLNode* leftRotate(AVLNode* x) {
        AVLNode* y = x->right;
        AVLNode* T2 = y->left;
        
        // 旋转
        y->left = x;
        x->right = T2;
        
        // 更新高度
        x->height = 1 + max(getHeight(x->left), getHeight(x->right));
        y->height = 1 + max(getHeight(y->left), getHeight(y->right));
        
        return y;
    }
    
    // 插入辅助函数
    AVLNode* insertHelper(AVLNode* node, int key, int value) {
        if (!node) {
            size++;
            return new AVLNode(key, value);
        }
        
        if (key < node->key) {
            node->left = insertHelper(node->left, key, value);
        } else if (key > node->key) {
            node->right = insertHelper(node->right, key, value);
        } else {
            node->value = value;  // 更新值
            return node;
        }
        
        // 更新高度
        node->height = 1 + max(getHeight(node->left), getHeight(node->right));
        
        // 获取平衡因子
        int balance = getBalance(node);
        
        // 平衡调整
        // 左左情况
        if (balance > 1 && key < node->left->key) {
            return rightRotate(node);
        }
        
        // 右右情况
        if (balance < -1 && key > node->right->key) {
            return leftRotate(node);
        }
        
        // 左右情况
        if (balance > 1 && key > node->left->key) {
            node->left = leftRotate(node->left);
            return rightRotate(node);
        }
        
        // 右左情况
        if (balance < -1 && key < node->right->key) {
            node->right = rightRotate(node->right);
            return leftRotate(node);
        }
        
        return node;
    }
    
    // 查找辅助函数
    AVLNode* searchHelper(AVLNode* node, int key) {
        if (!node || node->key == key) {
            return node;
        }
        
        if (key < node->key) {
            return searchHelper(node->left, key);
        } else {
            return searchHelper(node->right, key);
        }
    }
    
    // 销毁树
    void destroyTree(AVLNode* node) {
        if (!node) return;
        destroyTree(node->left);
        destroyTree(node->right);
        delete node;
    }
    
public:
    AVLTree() : root(nullptr), size(0) {}
    ~AVLTree() { destroyTree(root); }
    
    void insert(int key, int value) {
        root = insertHelper(root, key, value);
    }
    
    int search(int key) {
        AVLNode* node = searchHelper(root, key);
        return node ? node->value : -1;
    }
    
    int getSize() const { return size; }
    
    int getHeight() { return getHeight(root); }
    
    bool isBalanced() {
        return isBalancedHelper(root);
    }
    
    bool isBalancedHelper(AVLNode* node) {
        if (!node) return true;
        
        int balance = getBalance(node);
        if (abs(balance) > 1) return false;
        
        return isBalancedHelper(node->left) && isBalancedHelper(node->right);
    }
    
    void printInfo() {
        cout << "AVL Tree - Size: " << size 
             << ", Height: " << getHeight() 
             << ", Balanced: " << (isBalanced() ? "Yes" : "No") << endl;
    }
};

// ==================== 8. B树查找 ====================
/**
 * 时间复杂度: O(log n)
 * 空间复杂度: O(n)
 * 适用: 磁盘存储,数据库索引
 */

class BTree {
private:
    struct BTreeNode {
        vector<int> keys;
        vector<BTreeNode*> children;
        bool leaf;
        int degree;  // 最小度数
        
        BTreeNode(int t, bool isLeaf) : leaf(isLeaf), degree(t) {}
        
        // 遍历节点
        void traverse() {
            int i;
            for (i = 0; i < keys.size(); i++) {
                if (!leaf) {
                    children[i]->traverse();
                }
                cout << keys[i] << " ";
            }
            if (!leaf) {
                children[i]->traverse();
            }
        }
        
        // 在节点中查找键
        int searchKey(int k) {
            int idx = 0;
            while (idx < keys.size() && keys[idx] < k) {
                idx++;
            }
            return idx;
        }
    };
    
    BTreeNode* root;
    int degree;  // 最小度数
    
    // 插入辅助函数
    void insertNonFull(BTreeNode* node, int k) {
        int i = node->keys.size() - 1;
        
        if (node->leaf) {
            // 如果是叶节点,直接插入
            node->keys.push_back(0);  // 扩展数组
            while (i >= 0 && node->keys[i] > k) {
                node->keys[i+1] = node->keys[i];
                i--;
            }
            node->keys[i+1] = k;
        } else {
            // 找到要插入的子节点
            while (i >= 0 && node->keys[i] > k) {
                i--;
            }
            
            // 如果子节点已满,先分裂
            if (node->children[i+1]->keys.size() == 2*degree - 1) {
                splitChild(node, i+1, node->children[i+1]);
                if (node->keys[i+1] < k) {
                    i++;
                }
            }
            insertNonFull(node->children[i+1], k);
        }
    }
    
    // 分裂子节点
    void splitChild(BTreeNode* parent, int i, BTreeNode* child) {
        BTreeNode* newChild = new BTreeNode(degree, child->leaf);
        
        // 移动后半部分键到新节点
        for (int j = 0; j < degree - 1; j++) {
            newChild->keys.push_back(child->keys[j + degree]);
        }
        
        // 如果不是叶节点,移动子节点指针
        if (!child->leaf) {
            for (int j = 0; j < degree; j++) {
                newChild->children.push_back(child->children[j + degree]);
            }
        }
        
        // 调整原节点的大小
        child->keys.resize(degree - 1);
        
        // 在父节点中为新子节点腾出空间
        parent->children.insert(parent->children.begin() + i + 1, newChild);
        parent->keys.insert(parent->keys.begin() + i, child->keys[degree - 1]);
    }
    
    // 查找辅助函数
    pair<BTreeNode*, int> searchHelper(BTreeNode* node, int k) {
        if (!node) return {nullptr, -1};
        
        int i = 0;
        while (i < node->keys.size() && k > node->keys[i]) {
            i++;
        }
        
        if (i < node->keys.size() && node->keys[i] == k) {
            return {node, i};
        }
        
        if (node->leaf) {
            return {nullptr, -1};
        }
        
        return searchHelper(node->children[i], k);
    }
    
    // 销毁树
    void destroyTree(BTreeNode* node) {
        if (!node) return;
        if (!node->leaf) {
            for (auto child : node->children) {
                destroyTree(child);
            }
        }
        delete node;
    }
    
public:
    BTree(int t) : root(nullptr), degree(t) {}
    ~BTree() { destroyTree(root); }
    
    // 遍历B树
    void traverse() {
        if (root) {
            root->traverse();
            cout << endl;
        }
    }
    
    // 查找键
    int search(int k) {
        auto result = searchHelper(root, k);
        if (result.first) {
            return result.first->keys[result.second];
        }
        return -1;
    }
    
    // 插入键
    void insert(int k) {
        if (!root) {
            root = new BTreeNode(degree, true);
            root->keys.push_back(k);
        } else {
            if (root->keys.size() == 2*degree - 1) {
                // 根节点已满,需要分裂
                BTreeNode* newRoot = new BTreeNode(degree, false);
                newRoot->children.push_back(root);
                splitChild(newRoot, 0, root);
                
                // 决定插入到哪个子节点
                int i = 0;
                if (newRoot->keys[0] < k) {
                    i++;
                }
                insertNonFull(newRoot->children[i], k);
                root = newRoot;
            } else {
                insertNonFull(root, k);
            }
        }
    }
    
    void printInfo() {
        cout << "B-Tree (degree=" << degree << ")" << endl;
        cout << "Inorder traversal: ";
        traverse();
    }
};

// ==================== 测试函数 ====================
void testSearchAlgorithm() {
    cout << "=== 查找算法测试 ===" << endl;
    
    // 生成测试数据
    const int n = 100000;
    vector<int> arr = generateSortedArray(n);
    
    // 测试目标
    int target = 50000;  // 存在的目标
    int missingTarget = 50001;  // 不存在的目标(奇数)
    
    cout << "数组大小: " << n << endl;
    cout << "目标值: " << target << " (存在), " << missingTarget << " (不存在)" << endl;
    
    // 1. 顺序查找
    cout << "\n1. 顺序查找测试:" << endl;
    clock_t start = clock();
    int idx1 = sequentialSearch(arr, target);
    clock_t end = clock();
    cout << "  查找 " << target << ": 索引=" << idx1 
         << ", 时间=" << fixed << setprecision(3) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    start = clock();
    int idx2 = sequentialSearch(arr, missingTarget);
    end = clock();
    cout << "  查找 " << missingTarget << ": 索引=" << idx2 
         << ", 时间=" << fixed << setprecision(3) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    // 2. 二分查找
    cout << "\n2. 二分查找测试:" << endl;
    start = clock();
    int idx3 = binarySearchIterative(arr, target);
    end = clock();
    cout << "  迭代查找 " << target << ": 索引=" << idx3 
         << ", 时间=" << fixed << setprecision(6) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    start = clock();
    int idx4 = binarySearchRecursive(arr, target);
    end = clock();
    cout << "  递归查找 " << target << ": 索引=" << idx4 
         << ", 时间=" << fixed << setprecision(6) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    // 3. 插值查找
    cout << "\n3. 插值查找测试:" << endl;
    start = clock();
    int idx5 = interpolationSearch(arr, target);
    end = clock();
    cout << "  查找 " << target << ": 索引=" << idx5 
         << ", 时间=" << fixed << setprecision(6) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    // 4. 斐波那契查找
    cout << "\n4. 斐波那契查找测试:" << endl;
    start = clock();
    int idx6 = fibonacciSearch(arr, target);
    end = clock();
    cout << "  查找 " << target << ": 索引=" << idx6 
         << ", 时间=" << fixed << setprecision(6) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    // 5. 哈希查找
    cout << "\n5. 哈希查找测试:" << endl;
    SimpleHashTable hashTable(1000);
    for (int i = 0; i < 1000; i++) {
        hashTable.insert(i, i*10);
    }
    
    start = clock();
    int val1 = hashTable.search(500);
    end = clock();
    cout << "  查找键500: 值=" << val1 
         << ", 时间=" << fixed << setprecision(6) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    // 6. 二叉搜索树查找
    cout << "\n6. 二叉搜索树测试:" << endl;
    BinarySearchTree bst;
    for (int i = 0; i < 1000; i++) {
        bst.insert(i, i*10);
    }
    
    start = clock();
    int val2 = bst.search(500);
    end = clock();
    cout << "  查找键500: 值=" << val2 
         << ", 树高度=" << bst.getHeight()
         << ", 时间=" << fixed << setprecision(6) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    // 7. AVL树查找
    cout << "\n7. AVL树测试:" << endl;
    AVLTree avl;
    for (int i = 0; i < 1000; i++) {
        avl.insert(i, i*10);
    }
    
    start = clock();
    int val3 = avl.search(500);
    end = clock();
    cout << "  查找键500: 值=" << val3 
         << ", 树高度=" << avl.getHeight()
         << ", 时间=" << fixed << setprecision(6) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    // 8. B树查找
    cout << "\n8. B树测试:" << endl;
    BTree btree(3);
    for (int i = 0; i < 50; i++) {
        btree.insert(i*2);
    }
    
    start = clock();
    int val4 = btree.search(50);
    end = clock();
    cout << "  查找键50: 值=" << val4 
         << ", 时间=" << fixed << setprecision(6) 
         << double(end-start)/CLOCKS_PER_SEC*1000 << "ms" << endl;
    
    // 布隆过滤器测试
    cout << "\n9. 布隆过滤器测试:" << endl;
    BloomFilter bloom(1000, 3);
    bloom.insert("apple");
    bloom.insert("banana");
    bloom.insert("cherry");
    
    cout << "  查询 'apple': " << (bloom.contains("apple") ? "可能存在" : "一定不存在") << endl;
    cout << "  查询 'orange': " << (bloom.contains("orange") ? "可能存在" : "一定不存在") << endl;
    bloom.printStats();
}

int main() {
    srand(time(0));
    
    // 运行测试
    testSearchAlgorithm();
    
    // 额外演示
    cout << "\n=== 额外演示 ===" << endl;
    
    // 二分查找变体演示
    vector<int> arr = {1, 2, 2, 2, 3, 3, 4, 5, 5, 6};
    cout << "\n数组: ";
    printArray(arr);
    
    int target = 2;
    cout << "查找 " << target << ":" << endl;
    cout << "  第一个位置: " << binarySearchFirst(arr, target) << endl;
    cout << "  最后一个位置: " << binarySearchLast(arr, target) << endl;
    cout << "  第一个>=2的位置: " << binarySearchLowerBound(arr, target) << endl;
    cout << "  第一个>2的位置: " << binarySearchUpperBound(arr, target) << endl;
    
    return 0;
}

算法性能对比表

算法平均时间最坏时间空间要求适用场景
顺序查找O(n)O(n)O(1)无序小数据,简单实现
二分查找O(log n)O(log n)O(1)有序静态有序数组
插值查找O(log log n)O(n)O(1)有序均匀分布字典、电话簿
斐波那契查找O(log n)O(log n)O(1)有序避免除法运算
哈希查找O(1)O(n)O(n)快速查找,键值存储
二叉搜索树查找O(log n)O(n)O(n)可比较动态查找表
AVL树查找O(log n)O(log n)O(n)可比较频繁插入删除
B树查找O(log n)O(log n)O(n)可比较数据库索引,磁盘存储

算法选择指南

  1. 数据是否有序?

    • 是 → 二分查找、插值查找、斐波那契查找
    • 否 → 顺序查找、哈希查找
  2. 数据规模多大?

    • 小数据 (<1000) → 顺序查找、二分查找
    • 大数据 (≥1000) → 哈希、树结构
  3. 查找频率如何?

    • 频繁查找 → 哈希表、建立索引
    • 偶尔查找 → 顺序查找
  4. 是否需要动态更新?

    • 静态数据 → 二分查找
    • 动态数据 → 二叉搜索树、AVL树、B树
  5. 内存是否充足?

    • 内存充足 → 哈希表
    • 内存受限 → 树结构
  6. 是否需要范围查询?

    • 需要 → 树结构
    • 不需要 → 哈希表

编译运行

# 编译
g++ -std=c++11 -O2 search_algorithms.cpp -o search

# 运行
./search

输出示例

=== 查找算法测试 ===
数组大小: 100000
目标值: 50000 (存在), 50001 (不存在)

1. 顺序查找测试:
   查找 50000: 索引=25000, 时间=2.456ms
   查找 50001: 索引=-1, 时间=4.123ms

2. 二分查找测试:
   迭代查找 50000: 索引=25000, 时间=0.001ms
   递归查找 50000: 索引=25000, 时间=0.002ms

3. 插值查找测试:
   查找 50000: 索引=25000, 时间=0.001ms

4. 斐波那契查找测试:
   查找 50000: 索引=25000, 时间=0.002ms

5. 哈希查找测试:
   查找键500: 值=5000, 时间=0.001ms

6. 二叉搜索树测试:
   查找键500: 值=5000, 树高度=20, 时间=0.002ms

7. AVL树测试:
   查找键500: 值=5000, 树高度=10, 时间=0.001ms

8. B树测试:
   查找键50: 值=50, 时间=0.001ms

9. 布隆过滤器测试:
   查询 'apple': 可能存在
   查询 'orange': 一定不存在
   Bloom Filter: 12/1000 bits set

这个实现包含了8种经典查找算法的完整C++代码,涵盖从简单到复杂、从内存到磁盘的各种查找场景。每种算法都有详细的注释和性能分析,可以直接编译运行测试。