python算法--树的结构

简述

这一节比较重要,讲述树这种数据结构以及一些常用的知识和应用。树这种结构,比 线性结构要复杂和灵活一点,所以可以实现更多的逻辑难题,相比于图的话用的又更多一点,所以需要多多练习。

树常见的几种例子:

1、生物物种分类体系;

2、计算机里面的文件系统;

3、HTML文档里面的嵌套标记

4、域名体系;

相关术语:

1、节点Node:里面保存着相应的数据值;

2、边Edge:每条边连接两个节点。具有出入方向,每个节点(除了根节点),有一个入边;

3、根root:没有入边的节点,在上面;

4、路径Path:由边依次连接在一起的一个列表

5、子节点:入边来自于同一节点的,称为这个节点的子节点;

6、父节点:有一个出边是所有连接节点的,是父节点;

7、兄弟节点:具有同一个父节点的,之间称为兄弟节点;

8、子树:一个节点和它的所有子孙节点,以及相关边的集合;

9、叶节点:没有子节点的节点称为叶节点;

10、层级:从根节点到达一个节点的路径包含的边的数量。如根节点是0层,根的子节点是1层;

11、高度:树中所有节点的最大层级称为树的高度;

二叉树的链表实现

一般的,习惯运用之前的链表去表示我们的树,为了快速理解和实现,我们主要研究二叉树:

class BinaryTree:
    def __init__(self,rootObj):
        self.key=rootObj
        self.left=None
        self.right=None

    def insertLeft(self,newObj):
        if self.left==None:
            self.left=BinaryTree(newObj)
        else:
            t=BinaryTree(newObj)
            t.left=self.left
            self.left=t


    def insertRight(self,newObj):
        if self.right==None:
            self.right=BinaryTree(newObj)
        else:
            t=BinaryTree(newObj)
            t.right=self.right
            self.right=t

首先实现了几个基本的点:

1、每个节点其实有三个内容,自身的值key,到左节点的链接left,和到右节点的链接right;

2、主要功能是–添加左节点和添加右节点:

3、按照正常思维,将新节点添加到叶子节点,就很复杂,需要确定很多参数;这里选择的是把新节点放到根的的下面节点,类似于一个插入的概念。

(在以前的链表章节,添加一个新节点,其实也是用的这种思维)

下面实现了一些二叉树的其他方法

    def getRight(self):
        return self.right

    def getLeft(self):
        return self.left

    def setRootObj(self,obj):
        self.key=obj

    def getRootObj(self):
        return self.key

主要就是获取左右子树,根节点数值,以及将根节点数值进行修改。

树的应用:表达式解析

表达式可以解析成树的结构,叶子节点放操作数,内部的节点则放相应的操作符。

将全括号表达式转换成相应的树结构:

1、碰到**(** 则添加左子节点,当前节点下降到该子节点;

2、碰到 + - * / 等操作符,则当前节点设置为操作符,新建右子节点,并下降到该右子节点;

3、碰到的是操作数,则当前节点设置为操作数,再上升到父节点;

4、碰到 则上升到父节点;

def buildParseTree(fpexp):
    fplist = fpexp.split()
    pStack = Stack()

    eTree =BinaryTree('')
    pStack.push(eTree)

    currentTree=eTree

    for i in fplist:
        if i=='(':
            currentTree.insertLeft('')
            pStack.push(currentTree)
            currentTree=currentTree.getLeft()
        elif i not in ['+','-','*','/',')']
            currentTree.setRootObj(int(i))
            parent=pStack.pop()
            currentTree=parent
        elif i in ['+','-','*','/']:
            currentTree.setRootObj(i)
            currentTree.insertRight('')
            pStack.push(currentTree)
            currentTree=currentTree.getRight()
        elif i == ')':
            currentTree=pStack.pop()
        else:
            raise ValueError

    return eTree

树的遍历

对一个数据机构中的所有数据进行访问,叫做遍历。线性结构中的访问太简单了,而对于树,图等数据结构则较为复杂,所以值得研究。

就二叉树来说,分为前序遍历,中序遍历和后序遍历。使用递归思想,完成遍历非常的简洁明了。

def preoder(tree):
    if tree:
        print(tree.getRootObj)
        preoder(tree.getLeft())
        preoder(tree.getRight())

def postorder(tree):
    if tree:
        postorder(tree.getLeft)
        postorder(tree.getRight)
        print(tree.getRootObj)
        
def inorder(tree):
    if tree:
        inorder(tree.getLeft)
        print(tree.getRootObj)
        inorder(tree.getRight)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值