1.汉诺塔问题
问题描述:相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
分析:我们先把盘子的个数设置为3。盘子数为3时,我们可以很容易计算出操作步骤数是7。步骤是:
- A-C
- A-B
- C-B
- A-C
- B-A
- B-C
- A-C
我们可以发现,不管盘子数量是多少,都必须先得把最大的盘上面的所有盘移动到B杆才行,然后移动最大的盘,再把剩下的盘从B杆移动到C杆。
这样可以总结出:当盘子数量为n时,我们需要把1到n-1号盘挪到B杆上,再把n号盘移动至C杆,再把B杆上的1到n-1号盘移动C杆。
具体步骤可以分为:
1.以C盘为中介,从A杆将1至n-1号盘移至B杆;
2.将A杆中剩下的第n号盘移至C杆;
3.以A杆为中介;从B杆将1至n-1号盘移至C杆。
在进行第一个步骤时,我们可以利用递归的思想,直至n=1,说明第一步完成,步骤三类似。
#include<stdio.h>
void hanoi(int n, char x, char y, char z)
{
if (n == 1)
{
printf("%c---> %c\n", x, z);
}
else
{
hanoi(n - 1, x, z, y);//第一个步骤
printf("%c---> %c\n", x, z);//把最大的盘移动到C杆
hanoi(n - 1, y, x, z);//把B杆上的盘移动到C杆。
}
}
int main(void)
{
int n;
scanf("%d", &n);
hanoi(n, 'X', 'Y', 'Z');
return 0;
}
2.快速排序
快速排序算法的基本思想是:通过一趟排序将待排序数据分割成独立的两部分,其中一部分的所有元素均比另一部分的元素小,然后分别对这两部分继续进行排序,重复上述步骤直到排序完成。
步骤:
- 先找一个基准点数,一般设为序列的中间数
- 然后设置两个标记变量i,j。i从左往右找比基准点数大的值,j从右往左找比基准点小的值。
- 找到后互相比较a[i]和a[j]的值,如果a[i]比a[j]大则互换元素,直到i>j,即i的位置超过了j的位置;
经过第一堂寻找排序,数组被分为了2个子序列,左边的值都小于基准点值,右边的值都大于等于基准点的值。再对这两个子序列再次使用上面的方法,直到子序列就剩下一个元素,递归结束。
#include<stdio.h>
void quicksort(int a[], int left, int right)
{
int i = left, j = right;
int temp;
int middle;
middle = a[(left + right) / 2];
while (i<=j)
{
//从左到右找到大于基准点的元素
while (a[i] < middle)
{
i++;
}
//从右到左找到小于等于基准点的元素
while (a[j] > middle)
{
j--;
}
//如果i<=j,则互换
if (i <= j)
{
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
if (left < j)//左边子序列再次使用上述方法
{
quicksort(a, left, j);
}
if (i < right)
{
quicksort(a, i, right);//右边也使用上述方法,直到子序列就剩下一个元素,排序结束
}
}
int main(void)
{
int array[] = { 73,108,111,119,101,70,105,115,104,67,46,99,111,109 };
int i, length;
length = sizeof(array) / sizeof(array[0]);
quicksort(array, 0, length - 1);
for (int i = 0; i < length; i++)
{
printf("%d ", array[i]);
}
return 0;
}
还有后续…