打印解决汉诺塔问题的所有步骤
1 void Move(int n, int start, int goal, int temp) 2 { 3 if (n >= 1) 4 { 5 Move(n - 1, start, temp, goal); //将最上面的n-1个盘子移到temp柱子上 6 printf("Move disk %d from %d to %d.\n", n, start, goal); //将第n个柱子移到goal柱子上 7 Move(n - 1, temp, goal, start); //将temp柱子上的n - 1个柱子移到goal柱子上 8 } 9 10 11 }
用递归方法求集合中的中位数
1 void Swap(ElementType *X, ElementType *Y) 2 { 3 ElementType temp; 4 temp = *X; 5 *X = *Y; 6 *Y = temp; 7 } 8 9 ElementType FindKthLargest(ElementType s[], int K, int Left, int Right) 10 { //在s[Left]……s[Right]中找第K大的元素 11 ElementType e = s[Left]; //简单取首元素为基准 12 int L = Left, R = Right; 13 14 while (1) 15 { 16 while ((Left <= Right) && (e <= s[Left])) Left++; 17 while ((Left < Right) && (e > s[Right])) Right--; 18 if (Left < Right) 19 Swap(&s[Left], &s[Right]); 20 else 21 break; //最终brak退出时,Left一定指向第二个集合的第一个元素 22 } 23 Swap(&s[Left - 1], &s[L]); 24 if ((Left - L - 1) >= K) 25 return FindKthLargest(s, K, L, Left - 2); //Left - 1是基准,所以下一次递归的右边界应该是Left - 2 26 else 27 if ((Left - L - 1) < K - 1) 28 return FindKthLargest(s, K - (Left - L - 1) - 1, Left, R); //K 先减去第一个集合的Left - L - 1个元素,在减去基准元素,所以下一次递归应该是在第二个集合中求第K - (Left - L - 1) - 1个元素 29 else 30 return e; //找到,返回 31 } 32 33 //封装前面这个查找函数 34 ElementType Median(ElementType s[], int N) 35 { 36 return FindKthLargest(s, (N + 1) / 2, 0, N - 1); 37 }
这个方法实际上利用了和快速排序相同的思路
简单选取S中的第一个元素e,根据e将集合S分为{e}和大于等于e的元素集合S1、小于e的元素集合S2; 然后通过判别集合S1的大小,将从S集合中找第K大数问题转换为在S1 和S2中的查找问题,由于S1或S2中的集合规模都比S小,这样就将复杂的问题转化为规模相对较小的问题,这也是递归函数的设计基础