多叉树的简单运用
如图所示的一个多叉树,我们以学校为根节点,求下列5个问题:
1.求网1的父级
2.求网络的子级
3.求网1的所有祖先级
4.求学校的所有子孙级
5.求网1的兄弟级
首先我们创建一个类Tree,用来将数据存储到树中,然后解决第一个问题:
#usr/bin/python #-*-coding:utf-8-*- class Tree(): childToParent=None def add(self,parent,child): if self.childToParent is None: self.childToParent={child:parent} else: self.childToParent[child]=parent def getParent(self,child): return self.childToParent.get(child,'没有父级') if __name__=='__main__': tree=Tree() tree.add(None,'学校') tree.add('学校','商学院') tree.add('学校','法学院') tree.add('学校','电子学院') tree.add('学校','计算机学院') tree.add('计算机学院','软件') tree.add('计算机学院','网络') tree.add('计算机学院','数据') tree.add('网络','网1') tree.add('网络','网2') tree.add('网络','网3') child='网1' parent=tree.getParent(child) print('{0}的上级是{1}'.format(child,parent)) child2='学校' parent2=tree.getParent(child2) print('{0}的上级是{1}'.format(child2,parent2))
输出结果是:
网1的上级是网络 学校的上级是None
因为我们在Tree定义的方法add的参数以父->子参数的模式,所以我们在输入数据时以父在前,子在后的模式输入,学校的父级是None。首先判断我们在类中设定了一个childToParent(初始值为None),在add方法中,首先判断childToParent是否为None,是则以child为key,parent为value创建一个字典,否则在原有字典childToParent中追加一个以child为key,parent为value的数据。接着我们又定义了一个方法,getParent,输入参数child,直接返回当前字典childToParent的child的value值,如果没有value,则返回'没有父级'。
第二个问题:
#usr/bin/python #-*-coding:utf-8-*- class Tree(): parentToChildren=None def add(self,parent,child): if self.parentToChildren is None: self.parentToChildren={parent:[]} children= self.parentToChildren.get(parent,[]) if len( children)==0: self.parentToChildren[parent]=children children.append(child) def getChildren(self,parent): return self.parentToChildren.get(parent,'没有子级') if __name__=='__main__': tree=Tree() tree.add(None,'学校') tree.add('学校','商学院') tree.add('学校','法学院') tree.add('学校','电子学院') tree.add('学校','计算机学院') tree.add('计算机学院','软件') tree.add('计算机学院','网络') tree.add('计算机学院','数据') tree.add('网络','网1') tree.add('网络','网2') tree.add('网络','网3') parent='计算机学院' children=tree.getChildren(parent) print('{0}的子级:{1}'.format(parent,children)) parent2='网1' children2=tree.getChildren(parent2) print('{0}的子级:{1}'.format(parent2,children2))
输出:
计算机学院的子级:['软件', '网络', '数据'] 网1的子级:没有子级
我们一样的在类Tree中创建一个parentToChildren(初始为None),接着我们创建方法add,参数一样是parent、child,接着我们判断parentToChildren是否为None,是则将parentToChildren创建为一个以parent为key,[]为value的一个字典,接着我们定义了一个对象children,取当前字典以parent为key的value值,如果没有value值则为一个空列表[](即getChildren),接着判断children的长度,如果为0则在字典中添加一个parent为key,children为value的数据,然后在children列表后追加参数child;如果长度不为空,则直接在列表children后追加参数child。总的来说就是创建了数个以parent为key,child组成的列表为value的字典。
3.求网1的所有祖先级:
#usr/bin/python #-*-coding:utf-8-*- class Tree(): childToParent=None parentToChildren=None def add(self,parent,child): if self.childToParent is None: self.childToParent={child:parent} else: self.childToParent[child]=parent def getParent(self,child): return self.childToParent.get(child,'没有父级') def getzuxian(self,sunzi): parent=self.getParent(sunzi) if parent is None: return [] zupu=self.getzuxian(parent) zupu.append(parent) return zupu if __name__=='__main__': tree=Tree() tree.add(None,'学校') tree.add('学校','商学院') tree.add('学校','法学院') tree.add('学校','电子学院') tree.add('学校','计算机学院') tree.add('计算机学院','软件') tree.add('计算机学院','网络') tree.add('计算机学院','数据') tree.add('网络','网1') tree.add('网络','网2') tree.add('网络','网3') parent='计算机学院' aa='网1' bb=tree.getzuxian(aa) print('{0}祖先是:{1}'.format(aa,bb))
得到:
网1祖先是:['学校', '计算机学院', '网络']
这段代码就是在问题1 的基础上再类中新写了一个方法getzuxian,它需要输入的参数为zisun,原理就是使用递归的方法不停的获取祖先的祖先,直到没有祖先返回空,即不停的调用获取到的父类,然后继续getParent(父类),将每一步获取的父类都添加在zupu中,最后返回zupu。
4.求学校的子孙级:
class Tree(): parentToChildren=None def add(self,parent,child): if self.parentToChildren is None: self.parentToChildren={parent:[]} children= self.parentToChildren.get(parent,[]) if len( children)==0: self.parentToChildren[parent]=children children.append(child) def getChildren(self,parent): return self.parentToChildren.get(parent,'没有下级') def getzs(self,zs,zu): child=self.getChildren(zu) if child == '没有下级': return for i in child: self.getzs(zs,i) zs.extend(child) # zs.append(child) if __name__=='__main__': tree=Tree() tree.add(None,'学校') tree.add('学校','商学院') tree.add('学校','法学院') tree.add('学校','电子学院') tree.add('学校','计算机学院') tree.add('计算机学院','软件') tree.add('计算机学院','网络') tree.add('计算机学院','数据') tree.add('网络','网1') tree.add('网络','网2') tree.add('网络','网3') parent='计算机学院' zu='学校' zs=[] tree.getzs(zs,zu) print('{0}的子孙是:{1}'.format(zu,zs))得到
学校的子孙是:['网1', '网2', '网3', '软件', '网络', '数据', '商学院', '法学院', '电子学院', '计算机学院']
在第二个代码的基础上新写了一个方法getzs,需要输入两个参数,zs(我们输入一个空[]),zu(学校)。首先我们调用getChildren获得zu的子级(child),然后判断是否为空,空着直接返回,否则使i遍历子级,然后递归每个子级的getzs(zs,i),然后在空列表zs中追加列表child(extend:组合两个列表为一个列表).
5.获取网1的兄弟级:
#usr/bin/python #-*-coding:utf-8-*- class Tree(): childToParent=None parentToChildren=None def add(self,parent,child): if self.childToParent is None: self.childToParent={child:parent} else: self.childToParent[child]=parent if self.parentToChildren is None: self.parentToChildren={parent:[]} children= self.parentToChildren.get(parent,[]) if len( children)==0: self.parentToChildren[parent]=children children.append(child) def getChildren(self,parent): return self.parentToChildren.get(parent,'没有下级') def getParent(self,child): return self.childToParent.get(child,'没有父级') def xiongdi(self,xx): parent=self.getParent(xx) kk=self.getChildren(parent) kk.remove(xx) return kk if __name__=='__main__': tree=Tree() tree.add(None,'学校') tree.add('学校','商学院') tree.add('学校','法学院') tree.add('学校','电子学院') tree.add('学校','计算机学院') tree.add('计算机学院','软件') tree.add('计算机学院','网络') tree.add('计算机学院','数据') tree.add('网络','网1') tree.add('网络','网2') tree.add('网络','网3') parent='计算机学院' xx='网1' xxx=tree.xiongdi(xx) print('{0}的兄弟是:{1}'.format(xx,xxx)) mm='电子学院' mmm=tree.xiongdi(mm) print('{0}的兄弟是:{1}'.format(mm,mmm))
得到:
网1的兄弟是:['网2', '网3'] 电子学院的兄弟是:['商学院', '法学院', '计算机学院']结合程序1,2,然后新写一个方法xiongdi(),输入的参数xx,然后使用getParent(xx)获取xx的父类,接着使用getChildren获取xx父类的子类,然后在子类中去掉xx(remove),将剩下的子类输出,即可得到所需值。