用递归法解决汉诺塔与快速排序算法

本文详细介绍了递归的概念,包括其基本原理和两个关键条件,并通过实例演示了汉诺塔问题和快速排序算法如何运用递归。通过这两个经典的计算机科学问题,读者将体验到递归在解决复杂问题时的精妙之处。

1. 什么是递归

递归,就是在运行的过程中调用自己。

2. 递归的两个条件

  1. 子问题须与原始问题为同样的事,且更为简单;
  2. 不能无限制地调用本身,比须有结束。

以上是关于递归的介绍,接下来以汉诺塔与快排两个实例去在代码感受递归的魅力!

汉诺塔问题

在这里插入图片描述
三个柱子,在X柱上有若干个圆环,从小到大排列好。现在要把这些圆环从X移到Z中,且一次只能移动一个,也必须遵循从小到大原则。

核心思想是:
每一回把X中最下面的移到Z中

以X中有64个圆环为例:

  1. 将前63个移到Y中
  2. 把第64个移到Z中
    现在问题回到了开始,只是只剩下63个圆环,且把Y上的圆环移到Z中
  3. 将前62个移到X中
  4. 将第63个移到Z中
//n 为汉诺塔层数 x,y,z表示三个柱,x借助y移到z
void hanoi(int n,char x,char y,char z)
 {
 	if(n<1){
 		return;
	 }
	 else if(n==1)
	 {
	 	printf("%c --> %c\n",x,z);
	 }
	 else
	 {
	 	hanoi(n-1,x,z,y);
	 	printf("%c --> %c\n",x,z);
	 	hanoi(n-1,y,x,z);
	 }
 }

完整代码为:

//汉诺塔
 #include <stdio.h>
 void hanoi(int n,char x,char y,char z);
 void hanoi(int n,char x,char y,char z)
 {
 	if(n<1){
 		return;
	 }
	 else if(n==1)
	 {
	 	printf("%c --> %c\n",x,z);
	 }
	 else
	 {
	 	hanoi(n-1,x,z,y);
	 	printf("%c --> %c\n",x,z);
	 	hanoi(n-1,y,x,z);
	 }
 }
 int main(void)
 {
 	int n;
 	printf("输入汉诺塔层数:\n");
 	scanf("%d",&n);
 	hanoi(n,'x','y','z');
 	return 0;
 }

在这里插入图片描述

快排算法
left、i为数组array[0]
right、j为数组array[8]
pivot为基准点 22
在这里插入图片描述
i从左向右遍历数组,当找到值大于或等于基准点,等下来。
j从右向左遍历数组,当找到值小于或等于基准点,等下来。
i与j互换

直到i>j
第一趟排序结束
此时使用递归去解,i>j时array被分成两个数组,array[left-j]与array[i,right]

void quick_sort(int array[],int left,int right)
{
	int i = left, j = right;
	int temp;
	int pivot;//基准点
	
	pivot = array[(left+right) / 2];
	while(i<=j)
	{
		//从左到右找到大于或等于基准点的元素
		while(array[i]<pivot)
		{
			i++;
		}
		//从右到左找到小于或等于基准点的元素
		while(array[j]>pivot)
		{
			j--;
		}
		//如果i<=j,则互换
		if(i<=j)
		{
			temp=array[i];
			array[i]=array[j];
			array[j]=temp;
			i++;
			j--;	
		} 
			
	}//第一趟排序 
	
	if(left<j)
	{
		quick_sort(array,left,j);
	}
	if(i<right)
	{
		quick_sort(array,i,right);
	}
	
}

完整代码

//递归实现的快速排序
#include <stdio.h>
void quick_sort(int array[],int left,int right)
{
	int i = left, j = right;
	int temp;
	int pivot;//基准点
	
	pivot = array[(left+right) / 2];
	while(i<=j)
	{
		//从左到右找到大于或等于基准点的元素
		while(array[i]<pivot)
		{
			i++;
		}
		//从右到左找到小于或等于基准点的元素
		while(array[j]>pivot)
		{
			j--;
		}
		//如果i<=j,则互换
		if(i<=j)
		{
			temp=array[i];
			array[i]=array[j];
			array[j]=temp;
			i++;
			j--;	
		} 
			
	}//第一趟排序 
	
	if(left<j)
	{
		quick_sort(array,left,j);
	}
	if(i<right)
	{
		quick_sort(array,i,right);
	}
	
}
int main(void)
{
	int array[] ={73,108,111,101,70,105,104,67,46,99,111,109};
	int i,length;
	length=sizeof(array) / sizeof(array[0]);
	quick_sort(array,0,length-1);
	printf("排序后结果是: \n");
	for(i=0;i<length;i++){
		printf("%d ",array[i]);
	}
	return 0;
}  

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值