插值搜索

       插值搜索核心代码由二分搜索(区间左闭右开)m = l + 1.0/2*(r - 1 - l) = 1.0(l + r - 1)/2 更改为m = l +1.0*(key - a[l])/(a[r - 1] - a[l])*(r - 1 - l).

 

       利用关键字所在位置的估值(key - a[l])/(a[r - 1] - a[l])代替1/2,对于随机分布为常规分布的关键字,平均时间复杂度lg lg N.即如果N为10亿,平均查找小于5次.

 

 

 

 

//
//  main.cpp
//  插值搜索
//
//  Created by Lance on 13-3-14.
//  Copyright (c) 2013年 Lance. All rights reserved.
//

#include <iostream>
#include <cstdio>

using std::cin;
using std::cout;
using std::endl;

typedef int Item;

#define key(A)				(A)
#define less(A, B)			(key(A) < key(B))
#define exch(A, B)			{ Item t = A; A = B; B = t; }
#define compexch(A, B)		if (less(B, A)) exch(A, B)

void insertion (Item a[], int l, int r) {		//插入排序
	int			i;
	for (i = r - 1; i > 1; --i)					//设置观察哨
		compexch(a[i - 1], a[i]);
	
	for (i = l + 2; i < r; ++i) {
		int			j = i;
		Item		v = a[i];
		while (less(v, a[j - 1])) {				//确定位置并移位数组
			a[j] = a[j - 1];
			--j;
		} // end of while
		a[j] = v;
	}
	
}


Item search (Item a[], Item key, int l, int r) {
	//插值搜索核心代码
	int			m = l + 1.0*(key - a[l])/(a[r - 1] - a[l])*(r - 1 - l);
	if (l > r)			return -1;
	if (key == a[m])	return m;
	if (key <  a[m])	return search(a, key, l, m);
	else				return search(a, key, m + 1, r);
}

int main(int argc, char *argv[]) {
    const int   N(10);
    int         i(0);
    Item         *a = new Item[N];
	
    
    for (i = 0; i < N; ++i)
        a[i] = 1000*(1.0*rand()/RAND_MAX);
	Item		compare(a[N/2]);
	
    
    printf("old data:\n");
    for (i = 0; i < N; ++i)
        printf("%3d ", a[i]);   //便于格式控制
    printf("\n");
    
	
    insertion(a, 0, N);

	
    printf("sorted:\n");
    for (i = 0; i < N; ++i)
        printf("%3d ", a[i]);
    printf("\n");
	
	int ans = search(a, compare, 0, N) + 1;
	cout << endl << endl;
	cout << "compare is " << compare << endl;
	cout << "ans is " << ans << endl;
    delete a;
}

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值