构造二叉树并实现访问操作

注意:
1.本博客仅供参考交流使用,请读者务必自行实践,切勿生搬硬套
2.由于笔者水平有限,若文中有错误或者可以改进之处,欢迎在评论区指出

不理会题目,直接阅读笔者构造树的代码不非常影响阅读

题目
Description

二叉树是结点的一个有限集合,该集合或者为空或者是由一个根结点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。

在定义树结点时,你的结点Node的属性应包括Node.elem, Node.lchild和Node.rchild等这三个属性,其分别代表节点的数据,节点的左孩子和节点的右孩子,属性的命名必须是elem、lchild和rchild。

同时,你需要根据输入数据建立一棵名为MyTree(注意大小写)的二叉树,该树拥有的变量应至少包含名为root(如MyTree.root)元素,代表该二叉树的根节点。

注意:本题树可能为空(树为空的情形指第一行无任何输入,即键入回车,空树没有任何结点)。

下面的代码是本题的main函数部分,最后三句代码的功能是执行输入的N条命令,请在代码块的地方添加根据输入的数据构造二叉树MyTree的代码块,注意代码块缩进的问题。

eval语句的功能是将接收到的字符串转换成命令并执行。

if name==‘main’:

#####################################

接收处理第一行数据并构造树的代码区域

#####################################

N = int(input())

for i in range(N):

eval(input())

Input
第一行字符表示要建立二叉树的元素(元素之间以空格分开),第二行表示待执行语句的行数n,接下来n行表示待执行的语句。

二叉树建立规则:按照完全二叉树的编号方式(根节点从0开始,然后从左到右,从上到下依次编号),第一行内各元素对应的索引即为该元素在完全二叉树中的位置,如样例中a(索引为0)为保存在根结点内的元素,特别注意‘#’代表不存在该节点,因此实际的二叉树中没有以‘#’为元素的结点。

Output
建立二叉树时无需输出二叉树;输入命令时会依次在每行输出相应命令的运行结果;当为空树(即树没有结点)时,访问该树的根节点(即MyTree.root)需输出None;当访问的节点不存在时,输出None。

Sample Input 1

a c d f # 11
2
print(MyTree.root.rchild.lchild.elem)
print(MyTree.root.lchild.lchild.elem)
Sample Output 1

11
f

要点

  1. 之前的博客提到**@property是让接下来的function可以作为一个属性来用,但这只是让它有了可读性,@funtion.settter**这种语句的作用就是使得这个function具有可写性,事实上 object.function = value其实就是 function(self,value)
  2. 怎么让节点按完全二叉树的顺序插入呢,这其实就是一个层次遍历的问题,先构造一个queue,先压入目前树的根节点,然后进入循环,使得第一个元素出队,第一个元素就代表了以这个节点为根节点的一棵树,若是该树左孩子为空,那么我们在这里插入一个节点,若否,检查右节点,若否,说明左右子树都存在,那么我们依次把左子树和右子树入队,循环进入下一轮。这就实现了层次插入。
  3. 题目中说到’#'代表这里没有节点,那麻烦大了,按我们要点2所讲的方法,这个点没有节点,也就是创建的时候跳过的话,下一轮的节点会在这个地方被插入,那就凉凉。因此我们照样存它。只是我们在返回一个Node的e时候若是发现elem为’#’,我们就返回None。
  4. if name==‘main’: 是什么意思呢,其实__name__的value就是你当前的文件的名字,__main__就是运行文件的名字,有些同学可能就说那这两个不是一个东西吗。其实就是 如果我们在这个文件上运行,就是应该东西,所以下面的代码会被运行,如果我们在其他文件里import这个文件,那么只会运行这个语句块之外的语句,起到一个保护作用。

Coding:

class Node(object):
    def __init__(self, lchild=None, rchild=None, elem=0):
        self._elem, self._lchild, self._rchild = elem, lchild, rchild

    @property
    def elem(self):
        if self._elem is '#':
            return None
        return self._elem

    @property
    def lchid(self):
        return self._lchild

    @property
    def rchild(self):
        return self._rchild

    @elem.setter
    def elem(self, elem):
        self._elem = elem

    @lchid.setter
    def lchild(self, lchild):
        self._lchild = lchild

    @rchild.setter
    def rchild(self, rchild):
        self._rchild = rchild


class BinTree(object):
    def __init__(self, elem=None):
        if elem is not None:
            self.root = Node(None, None, elem)
        else:
            self.root = None

    def append(self, elem):
        if self.root is None:
            self.root = Node(None, None, elem)
        else:
            queue = [self.root]
            while len(queue) > 0:
                cur = queue.pop(0)
                if cur.lchild is None:
                    cur.lchild = Node(None, None, elem)
                    return
                elif cur.rchild is None:
                    cur.rchild = Node(None, None, elem)
                    return
                else:
                    queue.append(cur.lchild)
                    queue.append(cur.rchild)

    def layer_order(self):
        if self.root is None:
            print('None')
        else:
            queue = [self.root]
            while queue:
                node = queue.pop(0)
                print(node.elem)
                if node.lchild is not None:
                    queue.append(node.lchild)
                if node.rchild is not None:
                    queue.append(node.rchild)


if __name__ == '__main__':

    #####################################

    #   接收处理第一行数据并构造树的代码区域   #
    MyTree = BinTree()
    temp_list = list(input().split(" "))
    if temp_list != ['']:
        for i in range(len(temp_list)):
            MyTree.append(temp_list[i])

    #####################################

   # MyTree.layer_order()

    N = int(input())

    for i in range(N):
        eval(input())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值