查找算法-二分、插值、斐波那契

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

/*
1、顺序查找 On
*/
int sequence_search(vector<int> data, int val)
{
    if (data.empty())
        return -1;
    for (int i = 0; i < data.size(); i++)
    {
        if (data[i] == val)
            return i;
    }
    return -1;
}

/*
2、有序表 二分查找 Ologn
找到返回下标,否则返回-1
不适应频繁插入删除,因为需要重排序
*/
int binary_search(vector<int> data, int val)
{
    if (data.empty())
        return -1;
    int low = 0;
    int high = data.size() - 1;
    int mid = 0;
    while (low <= high)
    {
        mid = (low + high) / 2;
        if (data[mid] == val)
            return mid;
        else if (data[mid] > val)//原表升序
            high = mid - 1;
        else
            low = mid + 1;
    }
    return -1;
}

/*
3、插值查找Ologn,优化二分查找的mid
基于二分查找算法,将查找点的选择改进为自适应选择
表长较大,关键字分布比较均匀,平均性能比折半查找要好的多
*/
int interpolation_search(vector<int> data, int val)
{
    if (data.empty())
        return -1;
    int low = 0;
    int high = data.size() - 1;
    int mid = 0;
    while (low <= high)
    {
        mid = low+(val-data[low])/(data[high]-data[low])*(high-low);
        if (data[mid] == val)
            return mid;
        else if (data[mid] > val)
            high = mid - 1;
        else
            low = mid + 1;
    }
    return -1;
}

/*
4、斐波那契查找 Ologn
平均性能优于二分查找,当key=1时,效率低于二分查找

新数组包含F[k]-1个数,mid=low+F[k-1]-1
low-mid有F[k-1]-1个数,mid-high有F[k-2]-1个数
*/
const int F_maxsize = 20;
void Fibonacci(vector<int> &F)
{
    F[0] = 1;
    F[1] = 1;
    for (int i = 2; i < F_maxsize; i++)
        F[i] = F[i - 1] + F[i - 2];
}
int fibonacci_search(vector<int> data, int val)
{
    if (data.empty())
        return -1;
    
    vector<int> F(F_maxsize, 0);
    Fibonacci(F);//得到F_maxsize大小的fibonacci数列

    int low = 0;
    int high = data.size() - 1;
    int mid = 0;

    int k = 0;
    while (data.size() > F[k] - 1)//让新数组记录个数为某个斐波那契数小1
        ++k;

    vector<int> temp(F[k] - 1, 0);//分配大小为F[k]-1的temp,前面放data,多余放data的最后一个数
    copy(data.begin(), data.end(), temp.begin());
    for (int i = data.size(); i < F[k] - 1; i++)
        temp[i] = data[data.size() - 1];
    
    while (low <= high)
    {
        mid = low + F[k - 1] - 1;
        if (temp[mid] > val)
        {
            high = mid - 1;
            k -= 1;//往前 f数列下标-1
        }
        else if (temp[mid] < val)
        {
            low = mid + 1;
            k -= 2;//往前 f数列下标-2
        }
        else
        {
            if (mid < data.size())
                return mid;
            else
                return data.size() - 1;
        }
    }
    return -1;
}

/*
5、二叉查找树查找 Ologn-On
6、平衡二叉树-红黑树、2-3树、B树、B+ 查找Ologn
7、哈希表查找 时间O1,若碰撞退化链表查询O同一索引元素个数  空间至少On
*/

int main()
{
    int a[] = { 1,4,3,2,5,6 };
    vector<int> data(a, a + 6);
    sort(data.begin(), data.end());//升序排序
    cout << "原序列:";
    for (vector<int>::iterator it = data.begin(); it != data.end(); it++)
        cout << *it << " ";
    cout << endl;
    
    cout << "1、顺序查找,下标为:" << sequence_search(data, 5) << endl;
    cout << "2、升序有序表 二分查找,下标为:" << binary_search(data, 5) << endl;
    cout << "3、升序有序表 插值查找,下标为:" << interpolation_search(data, 5) << endl;
    cout << "4、斐波那契查找,下标为:" << fibonacci_search(data, 5) << endl;
    
}

 

posted @ 2019-05-23 20:16  前进的code  阅读(477)  评论(0编辑  收藏  举报