算法设计与分析 实验一 递归与分治策略

本文详细介绍了使用C/C++编程语言实现的几种递归算法,包括阶乘、Ackerman函数、汉诺塔问题,以及二分搜索、合并排序和快速排序的递归实现。此外,还展示了非递归实现的二分搜索。这些算法在计算机科学中具有重要应用,是理解递归和排序算法的基础。
摘要由CSDN通过智能技术生成


实验平台:Visual studio 6.0 或者VS2008及以上(我用的DEV-C++)
编程语言:C语言或者C++语言

1.采用递归算法实现正整数10以内阶乘,并按照以下的顺序进行输出。

算法输入:10以内的正整数
算法输出:输入正整数的阶乘

阶乘函数可递归地定义为:

在这里插入图片描述

输出结果形式:
0!=1
1!=1
2!= 2
3!= 6
4!= 24
5!= 120
6!= 720
7!= 5040
8!= 40320
9!= 362880
10!= 3628800

#include <stdio.h>


int jiecheng(int n){
	int result = 0;
	if(n > 1){
		result = jiecheng(n-1) * n;
	}
	else{
		result = 1;
	}
	return result;
}

int main(){
	int n = 10;
	for (int i = 0;i <= n;i++){
		printf("%d! = %d\n",i,jiecheng(i));
	}
	return 0;
}

在这里插入图片描述

2. 采用递归算法实现Ackerman函数,并且计算n, m小于等于3的输出结果。

算法输入:n与m
算法输出:Ackerman函数的结果,即A (n, m)
Ackerman函数A(n,m)定义如下:
在这里插入图片描述
输出结果形式:
A(0,0)=1 A(0,1)=1 A(0,2)=1 A(0,3)=1
A(1,0)=2 A(1,1)=2 A(1,2)=2 A(1,3)=2
A(2,0)=4 A(2,1)=4 A(2,2)=4 A(2,3)=4
A(3,0)=5 A(3,1)=6 A(3,2)=8 A(3,3)=16

#include <stdio.h>

int ackerman(int n, int m){
	int result = 0;
	
	if (n == 1 && m == 0){
		result =2;
	}
	else if (n == 0 && m>=0){
		result = 1;
	}
	else if (n >=2 && m ==0){
		result = n+2;
	}
	else{
		result = ackerman(ackerman(n-1,m),m-1);
	}
	return result;
} 

int main(){
	int j = 0;
	int k = 0;
	int i = 0;
  for(j = 0;j <= 3; j++){
  	for (k = 0;k <= 3; k++){
  		i++;
  		if(i % 4 == 0){
  			printf("A(%d,%d)=%d\n",j,k,ackerman(j,k));
		  }
		else{
		  	printf("A(%d,%d)=%d\t",j,k,ackerman(j,k));
		  }
	  }
  }
}

在这里插入图片描述

3. 采用递归算法实现Hanoi塔问题

设a,b,c是3个塔座。开始时,在塔座a上有一叠共n个圆盘,这些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号为1,2,…,n,现要求将塔座a上的这一叠圆盘移到塔座b上,并仍按同样顺序叠置。在移动圆盘时应遵守以下移动规则:
规则1:每次只能移动1个圆盘;
规则2:任何时刻都不允许将较大的圆盘压在较小的圆盘之上;
规则3:在满足移动规则1和2的前提下,可将圆盘移至a,b,c中任一塔座上。
在这里插入图片描述
算法输入:圆盘的个数n,以及a,b,c三个塔座
算法输出:移动的规则顺序

#include <stdio.h>

int count = 0;

//打印移动方式 
void move(int id,char from,char to){
	printf("step %d: move %d from %c -> %c\n",++count, id, from, to);
}


void hanio(int n, char x,char y,char z){
	if(n == 0){
		return;
	}
	hanio(n-1, x, z, y); //将第n-1个圆盘从x通过z放到y 
	move(n, x, z);
	hanio(n-1, y, x, z);
}

int main(){
	int n = 0;
	scanf("%d", &n);
	hanio(n,'A','B','C');
}

在这里插入图片描述

4. 二分搜索技术的递归实现与非递归实现

给定已按升序排好序的n个元素a[0:n-1],现要在这n个元素中找出一特定元素x。
据此容易设计出二分搜索算法:

int BinarySearch(Type a[], const Type& x, int l, int r)
{
     while (r >= l){ 
        int m = (l+r)/2;
        if (x == a[m]) return m;
        if (x < a[m]) r = m-1; else l = m+1;
        }
    return -1;
} 

#include <stdio.h>

void BinarySearch(int a[],int number,int left,int right){
	
	while (right>=left){
	int mid = int((left + +right)/2);
	if (a[mid] == number){
		printf("数组中的第%d个数就是%d",mid+1, number);
		return;
	}
	else if(a[mid] > number){
		right = mid - 1;
	}
	else if(a[mid] < number){
		left = mid + 1;
	}
}
}

int main (){
	int n=0;
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	scanf("%d", &n);
	BinarySearch(a, n, 0,9);
}

#include <stdio.h>

int BinarySearch(int a[],int number,int left,int right){
	
	int mid = int((left + right)/2);
	if (a[mid] == number){
		printf("%d",mid);
		return mid;
	}
	if (left > right){
		return -1;
	}
	else if(a[mid] > number){
		right = mid;
		return BinarySearch(a, number,left, mid);
	}
	else if(a[mid] < number){
		left = mid;
		return BinarySearch(a, number,mid, right);
	}
}


int main (){
	int n=0;
	int a[10] = {0,1,2,3,4,5,6,7,8,9};
	scanf("%d", &n);
	BinarySearch(a, n,0,9); 
}

5. 合并排序的递归实现

基本思想:将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。
伪代码:

void MergeSort(Type a[], int left, int right)
   {
      if (left<right) {//至少有2个元素
      int i=(left+right)/2;  //取中点
      mergeSort(a, left, i);
      mergeSort(a, i+1, right);
      merge(a, b, left, i, right);  //合并到数组b
      copy(a, b, left, right);    //复制回数组a
      }
   }

算法输入:输入数组的个数,比如{1,3,4,5,10,2,41}
算法输出:排序好的数组,{1,2,3,4,5,10,41}

#include <stdio.h>

void MERGE(int *A, int left, int mid, int right)

{       
        int l = mid-left+1, r = right-mid, i;
        int L[l+1], R[r+1];
        for(i=0; i< l; i++)
        {
            L[i] = A[left+i];
        }

        for (i=0; i< r; i++)
        {
            R[i] = A[mid+i+1];
        }
        L[l] = 32767;
        R[r] = 32767;
        l = 0;
        r = 0;

        for(i=0; i< right-left+1; i++)
       {
            if(L[l] < R[r])
            {
                A[left+i] = L[l];
                l ++;
            }
            else{
                A[left+i] = R[r];
                r ++;
            }
        }
}

 

void MERGE_SORT(int *A, int left, int right)

{
        if(left < right)

        {
            int mid = (left + right) / 2;
            MERGE_SORT(A, left, mid);
            MERGE_SORT(A, mid + 1, right);
            MERGE(A, left, mid, right);
        }
}

int main()

{
        int A[500];
        int lens, i;
        printf("Please Enter the lenghth of array:");
        scanf("%d", &lens);
 

        printf("Please Enter the elements of the array:");

        for(i=0; i< lens; i++)
           scanf("%d", &A[i]);

        MERGE_SORT(A, 0, lens-1); 

        printf("the result of the sort is:\n");
        for(i=0; i< lens; i++)
        {
           printf("%d ", A[i]);
        }
        return 0;

}

在这里插入图片描述

6. 快速排序的递归实现

快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

快速排序是一种不稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

伪代码:

void QuickSort (Type a[], int p, int r)
{
      if (p<r) {
        int q=Partition(a,p,r);
        QuickSort (a,p,q-1); //对左半段排序
        QuickSort (a,q+1,r); //对右半段排序
        }
}

算法输入:输入需要排序的数组,比如{ 3, 21, 87, 1, 21, 10 }
算法输出:排好序的数组。{1,3,10,21,21,87}

#include<stdio.h>

void quicksort(int *a,int low,int high) {
	if(low < high) {
		int i = low;
		int j = high;
		int k = a[low];
		while(i < j) {
			while(i < j && a[j] >= k ) {
				j--;
			}
			if(i < j) {
				a[i++] = a[j];
			}
			while(i < j &&a[i] < k) {
				i++;
			}
			if(i < j) {
				a[j--] = a[i];
			}
		}
		a[i] = k;

		quicksort(a,low,i-1);
		quicksort(a,i+1,high);
	}
}

	int main() {

		int a[500];
		int lens, i;
		printf("Please Enter the lenghth of array:");
		scanf("%d", &lens);


		printf("Please Enter the elements of the array:");

		for(i=0; i< lens; i++)
			scanf("%d", &a[i]);

		quicksort(a, 0, lens-1);

		printf("the result of the sort is:\n");
		for(i=0; i< lens; i++) {
			printf("%d ", a[i]);
		}
		return 0;

	}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拔牙不打麻药

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值