欧几里得算法求最大公约数的递归和非递归实现

递归定义必须是有明确含义,是指必须一步比一步简单,最终是有终结的,绝不能无限循环下去

所有的递归函数都能找到对应的非递归定义

递归的性能相对于非递归来说,并没有性能上的优势,实际上,有时候使用循环的性能更好。如果使用循环,程序的性能可能更高,如果使用递归,程序可能更容易理解。如何选择要看什么对你更重要

第一种,用于计算gcd(m,n)的欧几里得算法(递归)

举个例子来简单的解释一下欧几里得算法的思路

欧几里得算法采用的方法是重复gcd(m,n)=gcd(n,m mod n),直到m mod n等于0。详细一点说,就是:

第一步:如果n=0,返回m的值作为结果,同时过程结束,否则,进入第二步

第二步:m mod n的余数赋值给r

第三步:将n的值赋给m,将r的值赋给n,返回第一步

比如说:

gcd(60,24)=gcd(24,60 mod 24)=gcd(24,12)=gcd(12,24 mod 12)=gcd(12,0)=12

#include<stdio.h>
#include<iostream>
using namespace std;
int gcd(int m,int n){  //辗转相除法+递归调用
   if(n==0)//如果n=0,返回m的值作为结果
       return m;
   else
      return gcd(n,m%n);//递归调用
}
int main(){
   int m,n;
   cout<<"输入两个数字m,n:";
   cin>>m>>n;
   cout<<"gcd("<<m<<","<<n<<") = "<<gcd(m,n)<<endl;
   return 0;
}

第二种,用于计算gcd(m,n)的连续整数检测算法(非递归)

第一步:将min{m,n}的值赋给t

第二步:m mod t 如果余数为0,进入第三步,否则进入第四步

第三步:n mod t 如果余数为0,返回 t 的值作为结果,否则进入第四步

第四步:将 t 的值减1,返回第二步

例如:gcd(60,24),该算法先会尝试24,然后是23,22……13,一直尝试到12,算法就结束了

#include<stdio.h>
#include<iostream>
using namespace std;
int gcd(int m,int n){ 
	int t;
	//将t=min(m,n)
	if(m>n)
		t=n;
	else
	    t=m;
	//连续整数检测算法
	while(t>0){
		if(m%t==0){
			if(n%t==0){
			   return t;
			}
		}
		t--;
	}
}
int main(){
   int m,n;
   cout<<"输入两个数字m,n:";
   cin>>m>>n;
   cout<<"gcd("<<m<<","<<n<<") = "<<gcd(m,n)<<endl;
   return 0;
}

第三种:欧几里得减法(非递归)

第一步:如果n=0,返回m的值作为结果,同时过程结束,否则进入第二步

第二步:将max(m-n,n)的结果赋值给 t ,将min(m-n,n)的结果赋值给r

第三步:将 t 的值赋值给m,将 r 的值赋值给n,返回第一步

#include<stdio.h>
#include<iostream>
using namespace std;
int gcd(int m,int n){ 
	int t,r;
	//欧几里得减法实现
	while(n!=0){
		//将t=max(m-n,n),r=min(m-n,n)
		if((m-n)>n){
		  t=m-n;
		  r=n;
		}
		else{
		  t=n;
		  r=m-n;
		}
		m=t;
		n=r;
	}
	return m;
}
int main(){
   int m,n;
   cout<<"输入两个数字m,n:";
   cin>>m>>n;
   cout<<"gcd("<<m<<","<<n<<") = "<<gcd(m,n)<<endl;
   return 0;
}

第四种:用于计算gcd(m,n)的欧几里得算法非递归调用

#include<stdio.h>
#include<iostream>
using namespace std;
//辗转相除法+非递归调用
int gcd(int m,int n){ 
   int min,max,temp;
   if(m>n){  //交换m,n的位置,使得放在前面的为最大的
     min=n;
     max=m;
   }
   else{
       min=m;
       max=n;
   }
   //辗转相除+循环
   while(max%min){
     temp=max%min;
     max=min;
     min=temp;
   }
   return temp;
}
int main(){
   int m,n;
   cout<<"输入两个数字m,n:";
   cin>>m>>n;
   cout<<"gcd("<<m<<","<<n<<") = "<<gcd(m,n)<<endl;
   return 0;
}

猜你喜欢

转载自blog.csdn.net/zmeilin/article/details/81142114