数据结构 C语言版 第2版 李云清 杨庆红 揭安全 第5章_递归新.pptVIP

  • 19
  • 0
  • 约 58页
  • 2015-12-24 发布于广东
  • 举报

数据结构 C语言版 第2版 李云清 杨庆红 揭安全 第5章_递归新.ppt

else {pre1=1.0; pre2=x; for (i=2;i=n;++i) { a=2*i-1; b=i-1; valuep=(a*pre2*x-b*pre1)/i; pre1=pre2; pre2=valuep; } return(valuep); } } 复杂递归问题在求解的过程中无法保证求解动作一直向前,往往需要设置一些回溯点,当求解无法进行下去或当前处理的工作已经完成时,必须退回到所设置的回溯点,继续问题的求解。因此,在使用非递归方式实现一个复杂递归问题的算法时,经常使用栈来记录和管理所设置的回溯点。 5.3.2 复杂递归程序到非递归程序的转换 5.3.2 复杂递归程序到非递归程序的转换 例7 按中点优先的顺序遍历线性表问题:已知线性表list以顺序存储方式存储,要求按以下顺序输出list中所有结点的值:首先输出线性表list中点位置上的元素值,然后输出中点左部所有元素的值,再输出中点右部所有元素的值;而无论输出中点左部所有元素的值还是输出中点右部所有元素的值,也均应遵循以上规律。 例如,已知数组list中元素的值为: 18??? 32 4 9 26 6 10 30 12 8 45 则list中元素按中点优先顺序遍历的输出结果为: 6 4 18 32 9 26 12 10 30 8 45 试采用递归和非递归算法实现该遍历问题。 Left mid-1 mid mid+1 right 递归实现算法如下: #define MAXSIZE 20 typedef int listarr[MAXSIZE]; void listorder(listarr list, int left, int right) { /*将数组段list[left..right]的元素按中点优先顺序输出*/ int mid; if (left=right) { mid=(left+right)/2; printf(%4d,list[mid]); listorder(list,left,mid-1); listorder(list,mid+1,right); } } 下面考虑该问题的非递归实现:在线性表的遍历过程中,输出中点的值后,中点将线性表分成前半部分和后半部分。接下来应该考虑前半部分的遍历,但在进入前半部分的遍历之前,应该将后半部分保存起来,以便访问完前半部分所有元素后,再进入后半部分的访问。 即在此设置一个回溯点,该回溯点应该进栈保存,具体实现时,只需将后半部分起点和终点的下标进栈即可,栈中的每个元素均代表一个尚未处理且在等待被访问的数组段。对于每一个当前正在处理的数组(数组段)均应采用以上相同的方式进行处理,直到当前正在处理的数组(数组段)为空,此时应该进行回溯,而回溯点恰巧位于栈顶。于是只要取出栈顶元素,将它所确定的数组段作为下一步即将遍历的对象,继续线性表的遍历,直到当前正在处理的数组段为空且栈亦为空(表示已无回溯点),算法结束。 #define MAXSIZE 20 typedef int listarr[MAXSIZE]; void listorder(listarr list,int left, int right) { typedef struct { int l; /*存放待处理数组段的起点下标*/ int r; /*存放待处理数组段的终点下标*/ } stacknode; /*栈中每个元素的类型*/ stacknode stack[MAXSIZE]; int top,i,j,mid; /*top为栈顶指针*/ if (left=right) /*数组段不为空*/ { top= -1; i=left; j=right; while (i=j || top!=-1) {/*当前正在处理的数组段非空或栈非空*/ if (i=j) { mid=(i+j)/2; printf(“%4d”,list[mid]); ++top

文档评论(0)

1亿VIP精品文档

相关文档