C語言—遞歸二分法查找

分治策略:分解的是規模,比如數10億硬幣,分成4萬個人區完成,這樣,問題不會改變,改變的是問題的規模

下面是不用遞歸求階乘的方式

int fun(int n)
{
    int sum=1;
    for(int i=1;i<=n;i++)
    {
       sum=sum*(sum+1);
    }
}
void main{
int n,sum;
cin>>n;
sum=fun(n);
sum=fac(n);
}

這是遞歸的算法

int fac(n)
{
if(n<=1) return 1;
else return fac(n-1)*n;
}

fun(n)的時間複雜度是O(n),空間複雜度爲O(1)是一個定值,不會隨着i的範圍變化開闢更大的內存空間。fac(n)的時間複雜度是O(n),空間複雜度爲O(n)。所以在能用循環的時候儘量少使用遞歸。雖然遞歸的代碼簡潔。
系統默認給每個程序分配的棧大小爲1M,有死循環之說,但是沒有無限遞歸之說,如果遞歸要使用很多次時,要注意超出範圍。
在這裏插入圖片描述
上圖爲一個無限遞歸的例子
下面是二分法查找的使用循環的操作

#define error -1
int binaryfindvalue(Seqlist&seq, const elemtype val)
{
	int left = 0;
	int right = seq.cursize-1;
	int mid;
	while (1)
	{
	    if (left < right)
		{
			return error;
		}	
		mid = (left + right) / 2;//如果擔心數據範圍超過int的最大範圍
		                         //這裏的式子改爲(right -left+1)/2+left
		if (val < seq.data[mid])
		{
			right = mid - 1;
		}
		else if (val > seq.data[mid])
		{
			left = mid + 1;
		}
		else return mid;
			
	}
}

如果我們使用遞歸的做法,程序如下

int C_binaryfindvalue(Seqlist&seq, const elemtype val, int left, int right)
{
	if (left < right)
	{
		return error;
	}
	int mid = (right - left + 1) / 2 + left;
	if (val < seq.data[mid])
	{
		mid=C_binaryfindvalue(seq, left, mid - 1, val);
	}
	else if (val > seq.data[mid])
	{
		mid=C_binaryfindvalue(seq, mid+1, right, val);
	}
	else
	{
		while (mid>left&&seq.data[mid] == seq.data[mid - 1])//這樣是如果數據中存在多個重複的數,需要輸出第一位時的操作
		{
			mid--;
		}
	}return mid;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章