《递归的概念递归过程与递归工作栈递归与回溯广义表》由会员分享,可在线阅读,更多相关《递归的概念递归过程与递归工作栈递归与回溯广义表(61页珍藏版)》请在金锄头文库上搜索。
1、n n递归的概念递归的概念n n递归过程与递归工作栈递归过程与递归工作栈n n递归与回溯递归与回溯n n广义表广义表好壁琢恿磁墨傍蔽郑家啸蹿盅了矩捷墓蹿赖荷广棉磕收娶喇乎洗谷赏账忠递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归的概念n n递归的定义递归的定义 若一个对象部分地包含它若一个对象部分地包含它自己自己, 或用它自己给自己定义或用它自己给自己定义, 则称这则称这个对象是递归的;若一个过程个对象是递归的;若一个过程直接地或直接地或间接地调用自己间接地调用自己, 则称这个过程是递归则称这个过程是递归的过程。的过程。n n以下三种情
2、况常常用到递归方法。以下三种情况常常用到递归方法。n n 定义是递归的定义是递归的n n 数据结构是递归的数据结构是递归的n n 问题的解法是递归的问题的解法是递归的柴孺猩茶昔猾仆官洋新烦口迈傀顷年忘且哮统者久柔疏筏丧哨今慢瑚钵服递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表定义是递归的定义是递归的求解阶乘函数的递归算法求解阶乘函数的递归算法long Factorial ( long n ) if ( n = 0 ) return 1; else return n * Factorial (n-1);例如,阶乘函数例如,阶乘函数狙恐鱼婿弟姥眩瓣黑杏
3、堤冬涉搽薯刁媚砖绩油镐浴割笔滋适狠仰竟窄胜嚎递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表求解阶乘求解阶乘 n! 的过程的过程主程序主程序主程序主程序 main : fact(4)参数参数 4 计算计算 4*fact(3) 返回返回 24参数参数 3 计算计算 3*fact(2) 返回返回 6参数参数 2 计算计算 2*fact(1) 返回返回 2参数参数 1 计算计算 1*fact(0) 返回返回 1参数参数 0 直接定值直接定值 = 1 返回返回 1参参参参数数数数传传传传递递递递结结结结果果果果返返返返回回回回递递递递归归归归调调调调用用用用
4、回回回回归归归归求求求求值值值值靡笔摈帽汤既漂造疼邪碘蕊农庭佃胁伦泥献捆跋眺饺敬江溃俯缝猿赠飞丙递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表数据结构是递归的数据结构是递归的n n 一个结点,它的指针域为一个结点,它的指针域为NULL,是,是一个单链表一个单链表; ;n n 一个结点,它的指针域指向单链表,一个结点,它的指针域指向单链表,仍是一个单链表。仍是一个单链表。 例如,单链表结构例如,单链表结构f f 峭磅就才苗当掇粘弘抽歉空嗣泪燥曳赛申箍呐紫泪以钻做椎寺涂呈庚裁棉递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈
5、递归与回溯广义表搜索链表最后一个结点并打印其数值搜索链表最后一个结点并打印其数值template void Print ( ListNode *f ) if ( f -link = NULL ) cout data link );f f f f f a0a1a2a3a4递归找链尾又返季柿众应窒硫诱芋撼胰掂彬熊柔歇颇沮悦凋酞吨芜垛馋咆箩髓驰魂趴递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表在链表中寻找等于给定值的结点并打印在链表中寻找等于给定值的结点并打印其数值其数值template void Print ( ListNode *f, Type& x
6、 ) if ( f != NULL ) if ( f - data = x ) cout data link, x );f f f f 递归找含x值的结点x妆跪咋暮室推瞄赫月太倾抖婶素幕陈侥贷锦酮逢骸咬拂糜跳踩突雹工绝文递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 问题的解法是递归的问题的解法是递归的 例如,汉诺塔例如,汉诺塔(Tower of Hanoi)问题的解法:问题的解法: 如如果果 n = 1,则则将将这这一一个个盘盘子子直直接接从从 A 柱柱移移到到 C 柱上。否则,执行以下三步:柱上。否则,执行以下三步: 用用 C 柱柱做做过过渡渡
7、,将将 A 柱柱上上的的 (n- -1) 个个盘盘子子移移 到到 B 柱上:柱上: 将将 A 柱上最后一个盘子直接移到柱上最后一个盘子直接移到 C 柱上;柱上; 用用 A 柱做过渡,将柱做过渡,将 B 柱上的柱上的 (n- -1) 个盘子移个盘子移 到到 C 柱上。柱上。履铂始耿融侦怜菊髓除钱击深站抒透濒盼哀撼坚继鸣洋舌节谚暇钞蔑诀决递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表吁撇隘著烩夕意谁孔贴眼鸥箍岁匆价辩宵诅蓄爪筑轻缕唯俏试泄揪轴虏戌递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表#include
8、 #include strclass.h”void Hanoi (int n, String A, String B, String C) /解决汉诺塔问题的算法 if ( n = 1 ) cout move A to C endl; else Hanoi ( n-1, A, C, B ); cout move A to C endl; Hanoi ( n-1, B, A, C ); 俞沃若栖孽缩蓄玲抓漱粳拦撤框迫雅记请逗昏翠带初霉添揖好歧盒妹冕波递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表递归过程与递归工作栈递归过程与递归工作栈n n递归过程在
9、实现时,需要自己调用自己。递归过程在实现时,需要自己调用自己。n n层层向下递归,退出时的次序正好相反:层层向下递归,退出时的次序正好相反: 递归调用递归调用 n! (n-1)! (n-2)! 1! 0!=1 返回次序返回次序n n主程序第一次调用递归过程为主程序第一次调用递归过程为外部调用外部调用;n n递归过程每次递归调用自己为递归过程每次递归调用自己为内部调用内部调用。n n它们它们返回返回调用它的过程的调用它的过程的地址地址不同。不同。步魄馆匿硝逸拔凡铜惰埔碟绎胚霄荷盛谊建唉辑怕闽完技嚷慕挠囤魄答镇递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广
10、义表递归工作栈递归工作栈n n每一次递归调用时,需要为过程中使用的每一次递归调用时,需要为过程中使用的参数、局部变量等另外分配存储空间。参数、局部变量等另外分配存储空间。n n每层递归调用需分配的空间形成递归工作每层递归调用需分配的空间形成递归工作记录,按后进先出的栈组织。记录,按后进先出的栈组织。 局部变量局部变量返回地址返回地址参参 数数活动活动记录记录框架框架递归递归工作记录工作记录警豹愉顿误株试嗽一保诊窒沼冗循眷勾扇拭膜轧完牵庆汕驯峨杏酚堵澄污递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表函数递归时的活动记录函数递归时的活动记录.Funct
11、ion() .调用块函数块返回地址(下一条指令) 局部变量 参数墒住惹疫传潦族满崇较祸月目蠕馁账高庭藻恩龙骨舀破蒂济纳卿跑募协笛递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 long Factorial ( long n ) int temp; if ( n = 0 ) return 1; else temp = n * Factorial (n-1); RetLoc2 return temp; void main ( ) int n; n = Factorial (4); RetLoc1 二箍鼻蹦侨怖市娜洗器蛔贞尝偶贵唇绣柜训炬迄烯靖保胆馁贫缸
12、彼孩渔点递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表计算计算Fact时活动记录的内容时活动记录的内容递递归归调调用用序序列列0 RetLoc21 RetLoc22 RetLoc23 RetLoc24 RetLoc1参数参数参数参数 返回地址返回地址返回地址返回地址 返回时的指令返回时的指令返回时的指令返回时的指令RetLoc1 return 4*6 /返回返回返回返回2424 RetLoc2 return 3*2 /返回返回返回返回6 6 RetLoc2 return 1 /返回返回返回返回1 1 RetLoc2 return 1*1 /返回返回
13、返回返回1 1 RetLoc2 return 2*1 /返回返回返回返回2 2 肩镍狠钦杨搅旭李中懂狙拓倪衅致翌惜馅瞳挝名捂芋铣鄙蹦渠诫傍镭驯俏递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表递归过程改为非递归过程递归过程改为非递归过程n n递归过程简洁、易编、易懂递归过程简洁、易编、易懂n n递归过程递归过程效率低效率低,重复计算多,重复计算多n n改为非递归过程的目的是改为非递归过程的目的是提高效率提高效率n n单向递归单向递归和和尾递归尾递归可直接用可直接用迭代迭代实实现其非递归过程现其非递归过程n n其他情形必须借助其他情形必须借助栈栈实现非
14、递归过实现非递归过程程寞盘愿游晓带幢增枕比徊伤咯宫腐丈躬荷矛幽穆腊梭痢筛阑铝祭抹差伴痕递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表计算斐波那契数列的函数计算斐波那契数列的函数Fib(n)的定义的定义求解斐波那契数列的递归算法求解斐波那契数列的递归算法 long Fib ( long n ) if ( n = 1 ) return n; else return Fib (n-1) + Fib (n-2); 如如 F0 = 0, F1 = 1, F2 = 1, F3 = 2, F4 = 3, F5 = 5 沫贮煞碍歌遁帚墨鸵烃诫置楞呜释邑络莱屡篇椿烟
15、沼汛穗高踏慑敦气蒙洛递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表调用次数调用次数 NumCall(k) = 2* *Fib(k+1) - - 1斐波那契数列的递归调用树斐波那契数列的递归调用树Fib(1) Fib(0)Fib(1)Fib(2)Fib(3)Fib(4)Fib(1) Fib(0)Fib(2)Fib(1) Fib(0)Fib(1)Fib(2)Fib(3)Fib(5)忠棋察绸歪善巍誊盂居纪闺烃庆税煽炕温渐捶奖甚菌雹闺痰啸断昏皑坊吨递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表Fib(1)Fib
16、(0)Fib(2)Fib(1)Fib(0)Fib(2)Fib(1)Fib(3)Fib(4)栈结点栈结点n tagtag = 1, 向左递归;向左递归;tag = 2, 向右递归向右递归侧獭蕴李赞愈衔涎识名娃罪嚣涨宝捐酬础飞窗沿倦履疲颊蛾痪忧祟耕拧悟递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表Fib(1)Fib(0)Fib(2)Fib(1)Fib(0)Fib(2)Fib(1)Fib(3)Fib(4)2 13 14 1 n=1sum=0+12 23 14 1n=2-23 14 1 n=0sum=1+03 24 1n=3-24 1 n=1sum=1+1
17、4 2n=4-2啤彦较们蛤镶获割甭沈畜醒物入幂鸽搁辆融返杯介让顶皱奴宅掂肪中鱼宰递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表Fib(1)Fib(0)Fib(2)Fib(1)Fib(0)Fib(2)Fib(1)Fib(3)Fib(4)2 14 2 n=1sum=2+12 24 2n=2-24 2 n=0sum=3+0数醚丽干肚厌钮悠收谚畅药设醇舌娇歌摧愚去墨昭皇弹勒芽爷弥磁愚削衔递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表long Fibnacci ( long n ) Stack S; Node *
18、w; long sum = 0; /反复执行直到所有终端结点数据累加完 do while ( n 1 ) w-n = n; w-tag = 1; S.push ( w ); n-; /向左递归到底, 边走边进栈 sum = sum + n; /执行求和 画隐块椒稻诞徊疗况次迂瞄逾悸府深邢目恼梢锅甥锋葱款栖踊肘施赤曼炳递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 while ( !S.IsEmpty( ) ) w = S.getTop( ); S.Pop( ); if ( w-tag = 1 ) /改为向右递归 w-tag = 2; S.push
19、( w ); n = w-n 2; /F(n)右侧为F(n-2) break; while ( !S.IsEmpty( ) );return sum;司茧湿语鹤狐昭前庆峙掐沼彭嗜蔓哺愚候揽鸭真揪剥萎鸣侈拜棱筷厚镣窘递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表单向递归用迭代法实现单向递归用迭代法实现long FibIter ( long n ) if ( n = 1 ) return n; long twoback = 0, oneback = 1, Current; for ( int i = 2; i = 0 ) cout An = 0 ) c
20、out value An endl; n-; 抄撮萌哑锈乐添莽犬红丈芥展阜缝晴澈蠕贼卖夸稀以印附经摸霓吓训纲涪递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表递归与回溯递归与回溯 常用于搜索过程常用于搜索过程n皇后问题皇后问题 在在 n 行行 n 列的国际象棋棋盘上,列的国际象棋棋盘上,若若两个皇后两个皇后位于位于同一行同一行、同一列同一列、同一对角线同一对角线上,则称为它们为上,则称为它们为互相互相攻击攻击。n皇后问题是指皇后问题是指找到这找到这 n 个个皇后的互不攻击的布局皇后的互不攻击的布局。箱巴峰倪嘘惠疟苯任隶受帮暑练蟹呜钨污娇鸽瞎执彝诵殆倾
21、溪朝瘫新换易递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表1#主对角线主对角线3#主对角线主对角线5#主对角线主对角线0#次对角线次对角线2#次对角线次对角线4#次对角线次对角线6#次对角线次对角线1#次对角线次对角线3#次对角线次对角线5#次对角线次对角线0#主对角线主对角线2#主对角线主对角线4#主对角线主对角线6#主对角线主对角线0 1 2 3 0123k = i+jk = n+i- -j- -1颁峪廊只卉呵遂殖跌打丧线泌园酿男磕矾晴斥志怜厌脉岗嘎丁拯缘另碾紊递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回
22、溯广义表解题思路解题思路n n安放安放第第 i 行行皇后时,需要在列的方向从皇后时,需要在列的方向从 0 到到 n-1 试探试探 ( j = 0, , n-1 ) n n在在第第 j 列列安放一个皇后:安放一个皇后:uu如果在如果在列列、主对角线主对角线、次对角线次对角线方向方向有其它皇后,则出现攻击,撤消在有其它皇后,则出现攻击,撤消在第第 j 列列安放的皇后。安放的皇后。uu如果没有出现攻击,在如果没有出现攻击,在第第 j 列列安放的安放的皇后不动,递归安放第皇后不动,递归安放第 i+1行皇后。行皇后。佃敖褥扰讶涌溶秧耽瞩莎九链鼓蓟繁拧报时磺邦腻蹿炯寇饰羊宵累仪频痴递归的概念递归过程与递归
23、工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表n n设置设置 4 个数组个数组u coln :coli 标识第标识第 i 列是否安列是否安放了皇后放了皇后u md2n-1 : mdk 标识第标识第 k 条主对条主对角线是否安放了皇后角线是否安放了皇后u sd2n-1 : sdk 标识第标识第 k 条次对角条次对角线是否安放了皇后线是否安放了皇后u qn : qi 记录第记录第 i 行皇后在第几行皇后在第几列列搞馅辱蝶驮屿邵豁样纵茹洁弗圣惑央旺钠宴僳勉渭座诫溅欺钙盅精吭畅蜀递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表void
24、Queen( int i ) for ( int j = 0; j n; j+ ) if ( 第第 i 行第行第 j 列没有攻击列没有攻击 ) 在第在第 i 行第行第 j 列安放皇后列安放皇后; if ( i = n-1 ) 输出一个布局输出一个布局; else Queen ( i+1 ); 撤消第撤消第 i 行第行第 j 列的皇后列的皇后; 泰测大砖耗孵芝说腆谈嫉屏座卞经徘滨囚哲颂餐攫甫瓶辣训咳畔匿太压同递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表算法求精算法求精void Queen( int i ) for ( int j = 0; j n;
25、 j+ ) if ( !colj & !mdn+i-j-1 & !sdi+j ) /*第第 i 行第行第 j 列没有攻击列没有攻击 */ colj = mdn+i-j-1 = sdi+j = 1; qi = j; /*在第在第 i 行第行第 j 列安放皇后列安放皇后*/ 殃谣马哗贩娥彦爹零疾季佰京镜罩软透吧沸屹渝爱广伸氰十赵幸畏嗣搂钝递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 if ( i = n-1 ) /*输出一个布局输出一个布局*/ for ( j = 0; j n; j+ ) cout qj ,; cout 0时,表的时,表的第一个表元
26、素第一个表元素称为广义表称为广义表 的的表头表头(head),除此之外,除此之外,其它表元素其它表元素组组 成的表成的表称为广义表的称为广义表的表尾表尾(tail)。 催檬哥朵寺赖衫移敬绑撂邯往找卜穗藐猿菜咸掇卢蔷笔纳尧抢禽颗撕雄适递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表广义表的特性广义表的特性n n有次序性有次序性n n有长度有长度A = ( )B = ( 6, 2 )C = ( a, ( 5, 3, x ) )D = ( B, C, A )E = ( B, D )F = ( 4, F )n n有深度有深度n n可共享可共享n n可递归可递
27、归粟甜拎仅勒完爱纳韵败窟赴泛朽窝梢住咙遣梆躇牵褥筛雍究龋玻勒砂疫鄂递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表猿稀逃彦冒攀膊婆稍衔独渣智皮硼秩镶辞佰帕鳞阉觅值肮木舆妥混苯朱杠递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表广义表的表示广义表的表示只包括整数和字符型数据的广义表链表表示只包括整数和字符型数据的广义表链表表示 表中套表情形下的广义表链表表示表中套表情形下的广义表链表表示5232436103914 list25list1 1247as番拭伯劲笆灿盟寐侣焙睫努衷吹品扣来郝肇厄有际却仇尖奄硒加怯姥
28、悲灵递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表广义表结点定义广义表结点定义n n结结点点类类型型 utype = 0, 表表头头;= 1, 整整型型原原子子;= 2, 字符型原子;字符型原子;= 3, 子表子表n n值值value utype=0时时, 存存放放引引用用计计数数(ref);utype=1时时 , 存存 放放 整整 数数 值值 (intinfo);utype=2时时, 存存放放字字符符型型数数据据(charinfo);utype=3时时, 存存放放指指向向子子表表表表头头的的指指针针(hlink)n n尾指针尾指针tlink ut
29、ype=0时时, 指向该表第一个指向该表第一个结点;结点;utype 0时时, 指向同一层下一个结点指向同一层下一个结点 utype value tlink 采椿樊莉钒款姜溺鹿泽筷蚁藻稳遁焰灿勘稠拾积磊磐肺班查怪亢芹舅魁嗽递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表广义表的存储表示广义表的存储表示E EBF F0 11 430 133D 0 11 51 32 x 0 12 a3 C C 0 13330 11 6D DB BBCA1 2 0 1A A 捷雾塘瘦擎乔痉稚呕老铅梦东峭恋暇获呼棠梧叭费作永束冤浅只痘寿尾纺递归的概念递归过程与递归工作栈递归
30、与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表广义表的类定义广义表的类定义class GenList; /GenList类的前视声明class GenListNode /广义表结点类的前视声明struct Items /仅有结点信息的项friend class GenlistNode;friend class Genlist; int utype; /0 / 1 / 2 / 3 union /联合 蘸囱枝摊腻茂尹牟父行烩酮誉蜕童灶胳沏夷举搁岂添啦瓮啃酷撤泞三郊烂递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 int ref; /utyp
31、e=0, 存放引用计数 int intinfo; /utype=1, 存放整数值 char charinfo; /utype =2, 存放字符 GenListNode *hlink; /utype =3, 存放指向子表的指针 class GenListNode /广义表结点类定义friend class Genlist;private: int utype; /0 / 1 / 2 / 3瑶抡行茸券饯王草你纠恩孕赦躬练抹舌某敌昼吹计牌矿吻翟万仰雏斋恍的递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 GenListNode * tlink;/下一结点指
32、针 union /联合 int ref; /utype=0, 存放引用计数 int intinfo; /utype=1, 存放整数值 char charinfo; /utype=2, 存放字符 GenListNode *hlink; /utype =3, 存放指向子表的指针 value;public: GenListNode ( ) : utype (0), tlink (NULL), ref (0) /构造函数, 建表头结点筛昆筐摹哇跟刃椎悸剑滁介沿窗起泌缠位拙明迎鞋鼠甲走削番晦攒鸽土留递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 GenLis
33、tNode ( int t, GenListNode *next = NULL ) /构造函数:建表结点 Items& Info ( GenListNode *elem ); /返回表元素elem的值 int nodetype ( GenListNode *elem ) return elem-utype; /返回表元素elem的数据类型 GenListNode& setInfo ( Items&x ); /将表元素elem中的值修改为x;蒂亦外过仪碟兜贷灰敷舱龙色久滇吩眺抓佰鸦马遍拙免姆拇嫡沿恩臂简也递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表
34、class GenList /广义表类定义 private: GenListNode *first; /广义表头指针 GenListNode *Copy ( GenListNode *ls ); /复制一个 ls 指示的无共享非递归表 int depth ( GenListNode *ls ); /计算由 ls 指示的非递归表的深度 int equal (GenListNode *s, GenListNode *t); /比较以s和t为表头的两个表是否相等 void Remove (GenListNode *ls ); /释放以 ls 为表头结点的广义表缸悍功粥琐婪泥挚揉阳伏喇称萤堑仲振徘彻绿
35、伙姆顿参帚拜包案帆娥厄蔡递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表public: Genlist ( ); /构造函数 GenList ( );/析构函数 GenListNode& Head ( ); /返回表头元素 GenList& Tail ( ); /返回表尾 GenListNode *First ( ); /返回第一个元素 GenListNode * Next ( GenListNode *elem ); /返回表元素elem的直接后继元素 void setNext ( GenListNode *elem1, GenListNode *
36、elem2 ); /将elem2插到表中元素elem1后 朱晦嫡孤概嚷掳滋记掉妇驱壹裹蹿磺桅涣既酒罗儡巨息催蔫筒馆咕酗己嘿递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 void Copy ( const GenList & l ); /广义表的复制 int depth ( ); /计算一个非递归表的深度 int Createlist ( GenListNode *ls, char * s );/从广义表的字符串描述 s 出发, /建立一个带表头结点的广义表结构 炒桥愚孵插勒御纱玫沂秤手熊逮纫吵理女睬堤蜜挞吴位速姜理恼牛聘挪灰递归的概念递归过程与递
37、归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表广义表的访问算法广义表的访问算法 广义表结点类的存取成员函数广义表结点类的存取成员函数Items& GenListNode : Info ( GenListNode * elem ) /返回表元素elem的值 Items *pitem = new Items; pitem-utype = elem-utype; pitem-value = elem-value; return * pitem;修咋离拣映谎凋卡窃矢锨烈炭恶闻瑚酱宝恿淆队刹恐脆仍狸砂乔盖建商诚递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归
38、工作栈递归与回溯广义表GenListNode& GenListNode :setInfo ( Items &x ) /修改表元素的值为 x utype = x-utype; value = x-value; 广义表类的构造和访问成员函数广义表类的构造和访问成员函数Genlist : GenList ( ) /构造函数 GenListNode *first = new GenListNode( ); first-utype = 0; first-ref = 1; first-tlink = NULL;识锭牢旦撑滞艳鞋宇饥伏县键龋洋占讲居裴映路埃窑汪杆俱夜结琳紊荧旱递归的概念递归过程与递归工作栈递
39、归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表Items& GenList : Head ( ) /若广义表非空,则返回其第一个元素的值,/否则函数没有定义。 if ( first-tlink = NULL ) return NULL; else /非空表 Items * temp = new Items; temp-utype = frist-tlink-utype; temp-value = frist-tlink-value; return * temp; /返回类型及值 逻递缓浅肢弃骤凸广信牡括燕滁允祭阻撇冤腮冶舞伺锑行钒俭谈攻汹囤恍递归的概念递归过程与递归工作栈递归与回
40、溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表GenList& GenList : Tail ( ) /若广义表非空,则返回广义表除第一个元/素外其它元素组成的表, 否则函数没有定义 if ( frist-tlink = NULL ) return NULL; else /非空表 GenList * temp; temp-first = Copy ( first ); return * temp; 戏职刚井打目逻克秩肚函鲍尘镇箕瞎痈炙琳鹿顶采九献柿淑馏狠格蝉晌椰递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表GenListNode * Gen
41、List : First ( ) if ( first-tlink = NULL ) return NULL; else return first-tlink;GenListNode * GenList : Next ( GenListNode *elem ) if ( elem-tlink = NULL ) return NULL; else return elem-tlink;彻脸跳逼挣钩迟外穆根剑孝翱褐米舌幅姜重愉脊显搔刨茨亢忽夕虑改颂悦递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表广义表的递归算法广义表的递归算法 广义表的复制算法广义表的复
42、制算法 void GenList : Copy ( const GenList& ls ) first = Copy ( ls.first );/共有函数GenListNode* GenList : Copy ( GenListNode* ls ) /私有函数 GenListNode *q = NULL; if ( ls != NULL ) q = new GenListNode ( ls-utype, NULL );彰恩牙范梧撤细弹赶勾滋槐熔淹扳踞颅海坎鸭奖苞擦甥翰耶贵氖猖即缅恭递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 switch ( l
43、s-utype ) case 0: q-value.ref = ls-value.ref; break; case 1: q-value.intgrinfo = ls-value.intgrinfo; break; case 2: q-value.charinfo = ls-value.charinfo; break; case 3: q-value.hlink = Copy (ls-value.hlink); 角陷矮危渗翼昧春最讽训磷身掌榆羡狰绒掐职溜媒扳斟婴港徘公殖安堵耽递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 q-tlink = Cop
44、y (ls-tlink); return q;捣艺趟烃裕俊彤气业酿辣秤搜嗣祖哀送堕雅吧降绦岸宽扫践呀塞独掖瘟碍递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表求广义表的深度求广义表的深度例如,对于广义表例如,对于广义表 E (B (a, b), D (B (a, b), C (u, (x, y, z), A ( ) ) )1111234熬几阻赐俯牟伦奶刁亡搂古掖认烹她钢勉原杨逐替锨米衅丑泉塌缠块汾杖递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表int GenList : depth ( GenListNo
45、de *ls ) if ( ls-tlink = NULL ) return 1; /空表 GenListNode * temp = ls-tlink; int m = 0; while ( temp != NULL ) /在表顶层横扫 if ( temp-utype = 3 ) /结点为表结点 int n = depth ( temp-value.hlink ); if ( m tlink; return m+1;烙尊踌掐宾遮较人踏虱屉楷右升挺闪约椒临芒雪砚锭茸鉴帛侦疼恶子吨裹递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表int GenList
46、: depth ( ) return depth ( first );广义表的删除算法广义表的删除算法0 11 5331 2 0 12 x 0 10 12 yls32 x 嘿胎赌蔼呸慧轴诸驭薯姿廓倾沧洒鸦羊涝菊励喳燃末饰颖色邮诅汾滤际嫩递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表n n扫描子链表扫描子链表uu 若结点数据为若结点数据为x, 删除。可以做循环删除。可以做循环连连 续删。续删。uu 若结点数据不为若结点数据不为x,不执行删除。,不执行删除。uu 若结点为子表,递归在子表执行删除。若结点为子表,递归在子表执行删除。void delval
47、ue(GenListNode * ls, const value x) /在广义表中删除所有含 x 的结点 if ( ls-tlink != NULL ) /非空表 GenListNode * p = ls-tlink;鹤隘恨网滦扫构岿限芦访兰痘烧啃瘪旧互才剿伤翔烩殉案牵半鄂朵坐安劈递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 while ( p != NULL & /横扫链表 ( ( p-utype = 1 & p-value.intinfo = x ) | ( p-utype = 2 & p-value.charinfo = x ) ) ls
48、-tlink = p-tlink; delete p; /删除 p = ls-tlink; /指向同一层后继结点 if ( p != NULL ) if ( p-utype = 3 ) /在子表中删除 delvalue ( p-value.hlink, x ); 小溪呵旅涉樱耀俏藏松绘科榆剧雏任慢眯颊竿袒炉披渊饼厘围涧饶杠层会递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 delvalue ( p, x ); /在后续链表中删除 GenList : GenList ( ) /析构函数 Remove ( first );void GenList :
49、Remove ( GenListNode *ls ) /私有函数:释放以 ls 为表头指针的广义表 ls-value.ref - ; /引用计数减1辞企扫断敬獭憾吟毯瞳契推扇御截俐诅杯坤满婿驹玖衅慕躁装吹税沟范甸递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表 if ( ls-value.ref = 0 ) /如果减到0 GenListNode *p = ls, *q; /横扫表顶层 while ( p-tlink != NULL ) q = p-tlink; /到第一个结点 if ( q-utype = 3 ) /递归删除子表 Remove ( q-value.hlink ); p-link = q-link; delete q; 麻挽至优肌骆戚疤潦怒浴以号永柯撂燥谎证惯敬烃缴揭桃胖善蔡员咆抡柞递归的概念递归过程与递归工作栈递归与回溯广义表递归的概念递归过程与递归工作栈递归与回溯广义表