数据类型二叉树之前就有写过,我曾一直认为,因为Python没有指针操作,所有实现起来会有麻烦,应该会用数组插入数组的方法进行实现。然后进行了尝试:
class Node:
date=None
left=None
right=None
class Tree:
def __init__(self):
self.Root=Node()
self.index=0
def Create_Tree(self,DateArray,ptr):
print('index',self.index)
print('date',DateArray[self.index])
if DateArray[self.index]=='#':
ptr.date='#'
self.index+=1
return
ptr.date=DateArray[self.index]
self.index+=1
ptr.left=Node()
ptr.right=Node()
self.Create_Tree(DateArray,ptr.left)
self.Create_Tree(DateArray,ptr.right)
def display(self,ptr):
if ptr.date=='#':
print('#')
return
print(ptr.date)
self.display(ptr.left)
self.display(ptr.right)
if __name__=="__main__":
x=Tree()
dates="ab##c##"
print(dates)
x.Create_Tree(DateArray=dates,ptr=x.Root)
x.display(x.Root)
print("over")
‘#’字符为空节点判断标志,这里任然实现了通过前序遍历的方法创建树,但是值得思考的是这里:
self.Create_Tree(DateArray,ptr.left)
self.Create_Tree(DateArray,ptr.right)
这里将Node的左节点和右节点作为参数传输函数中,如果按照C/C++的逻辑应该是拷贝一份变量传入,所以后面的赋值都没有意义,这里就存在了可变对象和不可变对象的问题。
再看一个例子:
class Node:
date=None
Next=None
def Fixed(ptr):
print(id(ptr))
ptr.date="test"
ptr.Next=None
print(id(ptr))
def Change(x):
print('change',id(x))
x=11
print(id(x))
if __name__=="__main__":
x=Node()
x.date="fantasy"
Fixed(x)
print(x.date)
c=22
Change(c)
print(c)
很清楚的知道,int类型的c通过函数修改其值需要加global所以,c不会改变
但是这里x通过函数属性被修改了,这两个对象在函数调用过程中地址均未发生改变,之所以会右这样的不同原因就在于int对象是不变对象,在c值被修改后吗,会发现c的地址也发生了改变。
**可变对象:**list,dict,set等,不会发生拷贝,直接对对象进行赋值。
**不可变对象:**int,float,string,tuple等,赋值时会重新开辟一段内存空间进行复制,然后变量再绑定到新的内存空间。
如果希望将对象最为参数传入函数并且不被修改,则需要进行拷贝,感觉就像人为的做了C/C++传参的操作,操作如下:
f __name__=="__main__":
x=Node()
x.date="fantasy"
print('x',id(x))
y=copy.copy(x)
print('y',id(x))
Fixed(y)
print(x.date)
此时对象x就没有被函数改变,可以看到x和y地址已经不同。
这里出现疑问deepcopy和copy同时实现了对对象的拷贝工作,其区别在哪里。
copy仅拷贝当前对象,deepcopy则拷贝当前对象及其子对象,也就说deepcopy后的对象与拷贝对象不再想干,而浅拷贝对象的子对象任然会受到拷贝对象子对象的影响。