一道数据结构问题,请问,这道11题,这里算法中为什么引入p?
首先,题主所说可以一直使用参数t而不引入p,在具体实现(c语言实现)中是完全正确的。甚至可以说不引入p可以节约一次赋值操作,效率更优。
如果回答地简单点,那就是“没有什么特殊含义,就是习惯如此而已”。
但是我们“过分”解读一下,这种习惯还是有其独到之处的。
这就不得不提到在思考问题中的递增的思考方式:
怎样健壮地实现功能
在以上基础上,怎样高效率地实现功能
在以上基础上,怎样优雅地实现功能
在以上基础上,怎样使得这种实现更具有一般性(划重点)
在以上基础上,怎样使得这种实现具有可扩充性、可复用性。
这也是在工程开发中要考虑的一些点。
所以:
1.这样写具有更高的通用性和一般性:我们知道,不是每个语言对参数的传递都是“传值”,我们可以把这段代码看成c语言,也可以看成伪代码。有些语言在函数内修改参数是可以影响到调用方的。根据普遍性来讲,这里复制一份比较具有通用性和一般性,因为这样写不管你用的是什么类型的语言都不会因为参数的传递方式不同而出现错误。
2.高扩扩性:在函数内部,在某很多些场合,我们尽量不去将参数直接拿来当变量,因为我们不知道什么时候会有改动需求,可能之后函数下面还需要用到原来参数的值,如果上面将参数改了,后面再进行扩充时就需要改变原有的、已经稳定了的代码——这无疑会带来风险和成本。
2023-08-15 广告
首先抛开这个题目不说,我们考虑一个函数 fun(int a) 和 fun(int *a), 他们的区别就是参数类型不同,简单分析可知,在main函数的作用域内传值过来第一个传变量名就可以,第二个要传变量的指针才行。那么在fun的作用域内有什么不同?
第一个只是传过来了一个值,第二个却传过来值对应的指针,也就是说第二个可以修改main作用域内那个变量的值,而第一个只能更改fun内的值,它怎么改对main的都无影响。我们这里称只能传值的两个变量的关系为同级变量,称指针为值变量的高一级变量。
然后我们看你这个题目,TBTNode * inLast(TBTNode *t),我猜TBTNode应该只是结构定义的结点类型,而非结点的指针类型,那么这里的参数TBTNode *t ,它的类型是指针类型,而实际在main内的实参应该也是TBTNode *类型,通常他是指向某个链表的头指针,题目说t为根,既可以是整棵树的根,也可以是整个树的某个结点,只是所求为它的子树。我们只管它是指向t结点的指针,然后它被传过来了,注意两个参数是同一级的变量,所以我们在inLast里面对t做什么对main里的那个t传过来的t无任何影响!
那为什么对于链表(这里二叉链也是链表)的各种运算的第一步都是找个p等于h?(仔细翻翻书,肯定都有这么个操作)
再仔细观察,这些运算有两类,一类只是对原链表取值性质就是读性质,并不会修改原链表,另一类就是会修改原链表内容的,比如删除结点添加结点,你再细心看这个第二类操作肯定使用的是结点指针的指针类型,也就是结点的二级指针类型。一级是因为链表的结构使用指针维护,二级同上面fun的作用,是为了能够具有修改功能。对于这一类操作,如果使用h直接做结点运算,那么边操作,边减链,就是说头指针一直往后跑,有什么后果?最后h不是指向头了,是指向最后运算那个结点。怎么解决?
用一个指针指向最开始头指针指向那个结点!
所以第一类操作只是沿用了这个习惯而已!至此问题回答完毕。