c++数据结构与算法

确定渐进复杂度示例:
渐进界限通过估算算法完成任务所需的时间和内存,来评估算法的效率。
大多数情况下我们只对时间复杂度感兴趣,他通常计算程序中赋值和比较操作的次数。
下面以对对数组元素简单求和:

for(i = sum = 0;i<n;i++)
{
		sum += a[i];
}

上面的语句首先初始化两个变量,然后执行了for循环n次,在每次迭代运算中都进行两次赋值。一个更新sum一个更新i,因此循环结束时一共进行了2n+2次赋值,这个算法的渐进复杂度是O(n)。
如果嵌套,算法的复杂度将会增加下面的算法输出从位置0开始的所有的子数组之和。

for( i=0;i<n;i++)
{ 
      for(j=1,sum=a[0];j<=i;j++)
      {
      		sum+=a[j];
      }
      cout<<i<<sum<<endl;
}

在循环开始之前,先初始化i,外层循环执行了n次,在外层循环每次迭代中都执行了for循环,给i,sum,j赋值并输出结果,对于每一个i ∈ \in {1,2,3,4,5,……,n-1},内层循环都执行了i次,在每次迭代中,都进行了两个赋值,一个是对sum赋值,一个是对j赋值因此一共进行了
q=n-1, 1+3n+ ∑ i = 1 q \sum_{i=1}^q i=1q 1+3n+2×(1+2+3+…+q)=1+3n+n(n-1)=O(n)+O(n2)=O(n2)
包含嵌套的算法,其复杂度通常包含一个循环的算法高,但这并非必然,例如如果要求输出从0位置开始的子数组的最后5个元素数字之和,可以将代码改写:

for(i=4;i<n;i++)
{
		for(j=i-3,sum=a[i-4];j<=i;j++)
		{
				sum+=a[i];
		}
		cout<<i-4<<i<<sum<<endl;
}

外层循环执行了n-4次,对于每个i,内层循环只执行4次,对外层循环的每一次执行来说,内层循环进行了8次赋值,这个数值并不一来数值大小。此外,i初始化,自动增加n-4次,j和sum初始化n-4次,所以程序执行了1+8(n-4)+3(n-4)=O(n)次赋值。
循环的执行的次数不依赖于数组的顺序。如果执行次数并不总是相同,就要计算渐进复杂度,可以用一个循环来说明这个问题。该循环用于判断按照升序排列的子数组的最大长度。例如在数组[1 8 1 2 5 0 11 12]中,他的子数组[1 2 5 ]最长,长度是3.
代码

for(i=0, length=1;i<n-1;i++)
{
	for(i1=12=k=i;k<n-1&&a[k]<a[k+1];k++,i2++)
	{
			if(length<i2-i1+1)
			length=i2-i1+1;
	}
}

注意,如果数组中所有的数值都按降序排列,外层循环会执行n-1次,但是在每一次迭代中,内层循环只执行一次,因此算法的复杂度是O(n)。如果数值按升序排列,栓发的效率将是最低的。在此情况下,外层for循环执行n-1次,对于每一个i ∈ \in {0,1,2,……,n-2},内层循环都执行n-1-i次。音系算法的复杂度是O(n2)。在大多数情况下,数据的排列是无序的,此时评估算法的效率是非常重要的。然而,评估平均情况下算法效率并没有什么价值。
二分法查找:
该算法用于在有序数组中查找一个元素。如果要在一个数组中查找数字k,该算法用于在有序数组中查找一个元素。如果要在数组中查找数字k,该算法就会先找到数组中间元素。如果此中间元素就是k,算法就返回他的位置,如果不是k,算法就继续。在第二次试探中,只考虑数组的一半,如果k
小于中间元素,那么只考虑第一部分,否则考虑第二部分。现在提取子数组的中间元素,并和k比较。如果相同,算法就成功,否则就把子数组分为两半,如果k大于中间的这个元素,就舍弃第一部分,否则,就留下第一部分这种划分和比较一直进行知道找到元素或者无法取中间值为止。

template<class T>
int binarySearch(const T arr[],int arrSize,const T& key)
{
	int lo = 0,mid,hi=arrSize-1;
	while(lo<=hi)
	{
		mid=(lo+hi)/2;
		if(key<arr[mid])
		hi=mid-1;
		else if(arr[mid]<key)
		lo=mid+1;
		else
		return mid;
	}
	return -1;
}

如果key正好位于数组中间,循环就执行一次。如果key不在数组中,算法把整个长度视为n,数组的一半就是n/2,一半的一半就是n/22,直到数组的长度为1,于是最后一项n/2m等于1,因此得到m=lgn。所以经过m次循环之后,才能判断k不在数组中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值