数据结构与算法分析:C语言描述 笔记1 (递归简论及练习题答案)

递归简论

递归的两个基本法则

1、 基准情形:你必须总要有某些基准的情形,他们不用递归就能求解。
2、 不断推进:对于那些需要递归求解的情形,递归调用必须总能够朝着产生基准情形的方向推进。

设计法则:假设所有的递归调用都能运行。
合成效益法则:在求解同一个问题的同一个实例时,切勿在不同的递归调用中做重复性的工作。

练习

1.1 编写一个程序解决选择问题。令k = N/2。画出表格显示你的程序对于N为不同值的运行时间。

#include <stdio.h>

#define ArrayNum 10
#define ResultNum (ArrayNum/2)

void JiangPaiXu(int* pArr, int num);

void main()
{
    
    
	int array[ArrayNum] = {
    
     9, 3, 10, 2, 25, 7, 8, 14, 17, 12 };
	for (int i = 0; i < ArrayNum; i++)
	{
    
    
		printf("%d ", array[i]);
	}
	printf("\n");
	// 从原始数组中取出ResultNum各元素,然后进行降排序
	int ResultArray[ResultNum];

	for (int i = 0; i < ResultNum; i++)
	{
    
    
		ResultArray[i] = array[i];
	}
	JiangPaiXu(ResultArray, ResultNum);
	for (int i = ResultNum; i < ArrayNum; i++)
	{
    
    
		if (ResultArray[ResultNum - 1] < array[i])
		{
    
    
			ResultArray[ResultNum - 1] = array[i];
			JiangPaiXu(ResultArray, ResultNum);
		}
	}
	
	printf("第k/2个值 : %d \n", ResultArray[ResultNum - 1]);	
}

void JiangPaiXu(int* pArr, int num)
{
    
    
	int temp;
	for (int i = 0; i < num -1; i++)
	{
    
    
		for (int j = 0; j < num - 1 - i; j++)
		{
    
    
			if (pArr[j] < pArr[j + 1])
			{
    
    
				temp = pArr[j];
				pArr[j] = pArr[j + 1];
				pArr[j + 1] = temp;
			}
		}
	}
}

1.2 编写一个程序求解字谜游戏问题。【参考文献1】【参考文献2

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define DICTSIZE 4			// 字典内最大单词数
#define WORDSIZE 21			// 单词最大长度 +1

char puzzle[4][4] = {
    
    
	{
    
    't', 'h', 'i', 's'},
	{
    
    'w', 'a', 't', 's'},
	{
    
    'o', 'a', 'h', 'g'},
	{
    
    'f', 'g', 'g', 't'}
};			// 字谜
char* dict[DICTSIZE] = {
    
     "this", "two", "fat", "that" };	// 字典

int wordExist(int x, int y, int dir, int maxChars, char* retWord);

void main()
{
    
    
	char word[WORDSIZE];
	for (int i = 0; i < 4; i++)				// 行
	{
    
    
		for (int j = 0; j < 4; j++)			//列
		{
    
    
			for (int d = 0; d < 8; d++)		// 方向
			{
    
    
				for (int n = 1; n <= 4; n++)	// 最大字符数
				{
    
    
					if (wordExist(i, j, d, n, word))
					{
    
    
						printf("%s\n", word);
						break;
					}
				}
			}
		}
	}
}

int wordExist(int x, int y, int dir, int maxChars, char* retWord)
{
    
    
	char str[WORDSIZE];
	int ct = 0;

	for (int i = 0; i < maxChars; i++)
	{
    
    
		// 添加(x, y)处的一个字符
		str[ct] = puzzle[x][y];
		str[ct + 1] = '\0';

		// 拿stc到字典内遍历
		for (int j = 0; j < DICTSIZE; j++)			// 第一次遍历时,是找一个字母的单词
		{
    
    
			if (strcmp(str, dict[j]) == 0)
			{
    
    
				strcpy(retWord, dict[j]);
				return 1;
			}
		}
		ct++;
		// 确定下一个字符位姿(x,y)
		switch (dir)
		{
    
    
			case 0:	// 从左到右
				y++;
				break;
			case 1:	// 从右到左
				y--;
				break;
			case 2:// 从上到下
				x++;
				break;
			case 3:// 从下到到上
				x--;
				break;
			case 4:// 从左上到右下
				x++;
				y++;
				break;
			case 5:// 从右下到左上
				x--;
				y--;
				break;
			case 6:// 从右上到左下
				x--;
				y++;
				break;
			case 7:// 从左下到右上
				x++;
				y--;
				break;
			default:
				printf("Direction error.");
				return 0;
		}
	}
	return 0;
}

注:此答案中有bug,若单个字母“a”,两个字母“at”。

1.3 只使用处理I/O的PrintDigit函数,编写一个过程以输出任意实数(可以是负的)。

#include <stdio.h>

void PrintDigit(int number);
void PrintOut(int N);

void main()
{
    
    
	int num = -72634;
	PrintOut(num);
}

void PrintDigit(int number)
{
    
    
	printf("%d ", number);
}

void PrintOut(int N)
{
    
    
	if (N >= 10 || N <= -10)
		PrintOut(N / 10);
	PrintDigit(N -(N/10)*10);
}

猜你喜欢

转载自blog.csdn.net/jlm7689235/article/details/108232391
今日推荐