递归

递归设计经验

1.找重复(分析问题,将问题转化成子问题,可以尝试“切蛋糕”的方法。子问题与原问题具有相同的形式,可以由一到多,例如T8汉诺塔,即将原问题化为多个子问题)

2.找重复中的变化量(需要传递到函数中的参数)

3.找出口(递归结束的点,参数变化到何值时可以结束)

注意:如果涉及的递归函数有返回值,函数中调用自身的那一行需要加一个return ,不然就算在后一层在出口位置返回了,也无法返回到最初的调用递归函数的位置,也就是没有返回值。在下面的T11在有空字符串的有序字符串数组中查找某一字符串(非空)中,可以体现这一点。但是如果不加return不报错,而且返回值一直是1,暂时还不知道这是为什么。

贴几个简单的递归例题训练递归思想。

T1 阶乘 O(1)+O(n-1)=O(1)+O(1)+O(n-2)...=O(n)

int factorial(int n)
{
	if(n == 2)
		return 2;
	else
		return n * factorial(n - 1); 
}  

T2 打印i-j        O(j-i)

void printi2j(int i,int j)
{
	if(i>j)
	{
		cout<<i<<endl;
		printi2j(i-1,j);	
	}	
	else if(i<j)
	{
		cout<<i<<endl;
		printi2j(i+1,j);
	}
	else
	{
		cout<<i;
		return;
	}
} 

T3 数组求和        O(1)+O(n-1)=O(1)+O(1)+O(n-2)...=O(n)

int sumArray(int *arr,int n)
{
	if(n == 0)
		return 0;
	else
		return arr[n-1] + sumArray(arr,n-1);
} 

T4 翻转字符串    O(1)+O(n-1)=O(1)+O(1)+O(n-2)...=O(n)

string reverseString(string str,int end) 
{
	if(end == 0)
		return "";
	return str[end-1]+reverseString(str,end-1);
	
}

T5 斐波那契数列    O(n-1)+O(n-2)+O(1)=2O(n-1)+O(1)=2(2O(n-2)+O(1))+O(1)... = O(2^n)

int Fibonacci(int n)
{
	if(n ==1 || n == 2)
		return 1;
	else
		return Fibonacci(n-1) + Fibonacci(n-2);
 } 

T6 辗转相除法    m%n < m/2 n%(m%n) < n/2 每迭代两次n减半,迭代k次,n变为n/2^(k/2)趋近于1时,有O(log n)

int division(int m,int n)
{
	if(n == 0)
		return m;
	else
		division(n,m%n);
} 

T7 插入排序改递归     O(n-1)+O(n)=O(n-2)+O(n)+O(n)...=O(n^2)

void insertSort_recursive(int arr[],int length)
{
	if(length == 0)
		return;
	insertSort_recursive(arr,length-1);
	int x = arr[length];
	int index = length-1;
	while(index>-1 && x<arr[index])
	{
		arr[index+1] = arr[index];
		index--;	
	} 
	arr[index+1] = x;
}

T8 汉诺塔(分三步,1-n从from到to,help辅助) 

void hanoiTower(int n,string from,string to,string help)
{
	if(n == 1)
	{
		cout<<"move "<<n<<" from "<<from<<" to "<<to<<endl;
		return;
	}
	else
	{
		hanoiTower(n-1,from,help,to);//1到n-1从from到help,to辅助 
		cout<<"move "<<n<<" from "<<from<<" to "<<to<<endl;//n从from到to 
		hanoiTower(n-1,help,to,from);//1到n-1从help到to,from辅助 
	}
} 

T9 爬楼梯 ,n阶台阶,每次爬1/2/3阶,求多少种爬楼梯方式  

int upStairs(int n)
{
	if(n == 0)
		return  0;
	if(n == 1)
		return 1;
	if(n == 2)
		return 2;
	if(n == 3)
		return 4;
	else
		return upStairs(n-1) + upStairs(n-2) + upStairs(n-3);
}

T10 旋转数组的最小数字

int rotateArray(int arr[],int low,int high)
{
	int mid;
	mid = low + ((high - low) >> 1);
	if(arr[low] == arr[mid] && arr[mid] == arr[high])//解决a[] = {4,3,4,4,4};
	{
		int min = arr[low];
		for(int i=low+1;i<=high;i++)
		{
			if(arr[i]<min)
				min = arr[i];
		}
		return min;
	}
	else if(arr[low] < arr[high])
		return arr[low];
	else if(low + 1 == high)
		return arr[high];
	else
	{
		if(arr[low] <= arr[mid])
			rotateArray(arr,mid,high);		
		else
			rotateArray(arr,low,mid); 
	}
 } 

T11 在有空字符串的有序字符串数组中查找某一字符串(非空)

int searchString(string arr[],int low,int high,string s)
{
	if(low == high)
	{
		//cout<<"????"<<endl;
		return -1;
	}	
	else
	{
		int mid = low + ((high - low) >> 1);
		//cout<<"mid = "<<mid<<endl;
		while(arr[mid] == "")
		{
			mid++;
			//cout<<mid<<endl;
			if(mid > high)
				return -1; 
			else
				continue;
		} 
		if(arr[mid] < s)
		{
			//cout<<"111111\t"<<mid<<endl;
			return searchString(arr,mid+1,high,s);
		}
		else if(arr[mid] > s)
		{
			//cout<<"222222\t"<<mid<<endl;
			return searchString(arr,low,mid-1,s);
		}
		else
		{
			//cout<<mid;
			return mid;
		}	
	}
 } 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值