代码调优:二分搜索

1,先给出一个经常用到的代码:
#include<iostream>
using namespace std;

int binarySearch1(int t, int data[], int n)
{
	int l = 0;
	int u = n - 1;
	int p, m;
	while (true)
	{
		if (l > u)
		{
			p = -1;
			break;
		}
		m = (l + u) / 2;
		if (data[m] < t)
			l = m + 1;
		else if (data[m] == t)
		{
			p = m;
			break;
		}
		else
			u = m -1;
	}
	return p;
}

int main()
{
    int data[]={1,4,4,5,6,8,9,9,9,9,9,10};
    int n=sizeof(data)/sizeof(data[0]);
    cout<<binarySearch1(9,data,n)<<endl;
    return 0;
}

缺点:
(1)每次循环至少需要比较两次;
(2)如果t多次出现,那么上述代码可能返回t的任意一个位置.

2,下面改进的代码,可以保证返回t第一次出现的位置.
#include<iostream>
using namespace std;

int binarySearch2(int t, int data[], int n)
{
	int l = -1;
	int u = n;
	int m;
	while ( (l + 1) != u)
	{
		m = (l + u) / 2;
		if (data[m] < t)
			l = m;
		else
			u = m;
	}
	int p = u;
	if ((u >= n) || (data[u] != t))
		p = -1;
	return p;
}

int main()
{
    int data[]={1,4,4,5,6,8,9,9,9,9,9,10};
    int n=sizeof(data)/sizeof(data[0]);
    cout<<binarySearch2(9,data,n)<<endl;
    return 0;
}


3,继续改进,循环展开将会有很大的提高.
#include<iostream>
#include<algorithm>
#include<iterator>
using namespace std;

const int N=1000;
int data[N];

int randInt()
{
    return rand()%(5000);
}

//这里设定数组的大小为1000
int binarySearch3(int t,int data[],int n)
{
    //第一步先保证搜索的范围为2的指数次.
    int i=512;
    int l=-1;
    if(data[511]<t)
        l=1000-512;
    while(i!=1)
    {
        if(data[l+i/2]<t)
            l=l+i/2;
        i=i/2;
    }
    //assert:i==1;data[l]<t;data[l+i]>=t
    int p=l+1;
    if(p>=n||data[p]!=t)
        p=-1;
    return p;
}

int binarySearch4(int t,int data[],int n)
{
    //第一步先保证搜索的范围为2的指数次.
    int l=-1;
    if(data[511]<t)
        l=1000-512;
    if(data[l+256]<t) l+=256;
    if(data[l+128]<t) l+=128;
    if(data[l+64]<t) l+=64;
    if(data[l+32]<t) l+=32;
    if(data[l+16]<t) l+=16;
    if(data[l+8]<t) l+=8;
    if(data[l+4]<t) l+=4;
    if(data[l+2]<t) l+=2;
    if(data[l+1]<t) l+=1;
    //assert:i==1;data[l]<t;data[l+i]>=t
    int p=l+1;
    if(p>=n||data[p]!=t)
        p=-1;
    return p;
}
int main()
{
    generate(data,data+N,randInt);
    sort(data,data+N);
    copy(data,data+N,ostream_iterator<int>(cout," "));
    cout<<endl;
    cout<<binarySearch3(447,data,N)<<endl;
    cout<<binarySearch4(447,data,N)<<endl;
    return 0;
}


你可能感兴趣的:(代码)