二分法的时间复杂度

查找算法中的“二分法”是这样定义的:

    给定N个从小到大排好序的整数序列List[],以及某待查找整数X,我们的目标是找到X在List中的下标。即若有List[i]=X,则返回i;否则返回-1表示没有找到。

    二分法是先找到序列的中点List[M],与X进行比较,若相等则返回中点下标;否则,若List[M]>X,则在左边的子系列中查找X;若List[M]<X,则在右边的子系列中查找X。

    试写出算法的伪码描述,并分析最坏、最好情况下的时间、空间复杂度。

#include "stdio.h"
int search_SS(int list[],int i,int length)
{
	int result;
	int low,mid,high;
	low = 1;
	high = length;
	while(low <= high)
	{
		mid = (int)((low+high)/2.0);
		if(list[mid] < i)
			low = mid+1;
		else if(list[mid] > i)
			high = mid-1;
		else
		{
			result = mid;
			return result;
		}
		
	}
	return result = -1;
}
int main()
{
	int list[] = {1,2,3,4,5,6,7,8,9};
	int i,length;
	int result;
	length = sizeof(list)/sizeof(int);
	/*
	向子函数传递数组后,然后在子函数内部获取数组长度。先来看一个错误示例程序:
	[cpp] view plain copy
	
	  
		int  getLength(int array[]) 
		{ 
			int length; 
			length=sizeof(array)/sizeof(array[0]); 
			return length; 
		} 
		len = getLength(array); 
		printf("The length of array is %d\n",len); 
	这样得到的结果始终都是1。因为数组作为参数传给函数时传的是指针而不是数组,
	传递的是数组的首地址。在本示例中,函数名array传递到子函数后就完全退化为一个指针,
	该指针指向的是数组array所在的地址,即数组array第一个元素array[0]所在的地址。
	也就是说系统只是告诉该函数这个存储空间存有数据,但并没有告诉函数这个数据存储空间有多大。
	sizeof(array)的结果是指针变量array所占内存的字节数,具体大小与系统有关,
	一般在32位机器上占4个字节,array[0]是int类型,同样占4个字节,所以结果为1。
	所以要获得数组的长度最好在数组定义所在的区域内。 
	*/
	printf("数组长度为:%d\n",length);
	printf("Please insert the number you want to search:\n");
	scanf("%d",&i);
	result = search_SS(list,i,length);
	if(result == -1)
		printf("Can not found %d in the list!\n",i);
	else
		printf("The number you found  is in the %d position of list!\n",result);

}

时间复杂度最小为O(1),第一个就找到要找的数;
时间复杂度最大为O(log2 n),最后一次找到要找的数;

对于n个元素的情况:
第一次二分:n/2
第二次二分:n/2^2= n/4
......
m次二分:n/(2^m)
在最坏情况下是在排除到只剩下最后一个值之后得到结果,所以为
n/(2^m)=1;
2^m=n;
所以时间复杂度为:log2n 也即log(n);

空间复杂度两种情况下均为O(1);

发布了11 篇原创文章 · 获赞 7 · 访问量 5257

猜你喜欢

转载自blog.csdn.net/qq_35591140/article/details/79615969
今日推荐