二叉树算法

2024-05-11 04:19

1. 二叉树算法

二叉树是没有度为1的结点。

完全二叉树定义:
若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层从右向左连续缺若干结点,这就是完全二叉树。

完全二叉树叶子结点的算法:
如果一棵具有n个结点的深度为k的二叉树,它的每一个结点都与深度为k的满二叉树中编号为1~n的结点一一对应,这棵二叉树称为完全二叉树。
可以根据公式进行推导,假设n0是度为0的结点总数(即叶子结点数),n1是度为1的结点总数,n2是度为2的结点总数,由二叉树的性质可知:n0=n2+1,则n= n0+n1+n2(其中n为完全二叉树的结点总数),由上述公式把n2消去得:n= 2n0+n1-1,由于完全二叉树中度为1的结点数只有两种可能0或1,由此得到n0=(n+1)/2或n0=n/2,合并成一个公式:n0=(n+1)/2 ,就可根据完全二叉树的结点总数计算出叶子结点数。

因此叶子结点数是(839+1)/2=420

二叉树算法

2. 二叉树算法

二叉树的算法主要分为三种:先序遍历,中序遍历和后序遍历。二叉树(Binary Tree)是n(n>=0)个节点的有限集合,该集合或者空集(称为空二叉树),或者由一个根节点和两棵互不相交的,分别称为根节点的左子树和右子树的二叉树组成。                    扩展资料                         二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的'子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^(i 1)个结点;深度为k的二叉树至多有2^k 1个结点;对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0 = n2 + 1。二叉树算法常被用于实现二叉查找树和二叉堆。
    概念
    编辑 语音
    二叉树是每个节点最多有两个子树的有序树。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
    基本形态:
    二叉树也是递归定义的,其结点有左右子树之分,逻辑上二叉树算法有五种基本形态:
    (1)空二叉树——(a)
    (2)只有一个根结点的二叉树——(b);
    (3)右子树为空的二叉树——(c);
    (4)左子树为空的二叉树——(d);
    (5)完全二叉树——(e)
    注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。

3. 二叉树算法

二叉树是没有度为1的结点。
完全二叉树定义:
若设二叉树的高度为h,除第
h
层外,其它各层
(1~h-1)
的结点数都达到最大个数,第
h
层从右向左连续缺若干结点,这就是完全二叉树。
完全二叉树叶子结点的算法:
如果一棵具有n个结点的深度为k的二叉树,它的每一个结点都与深度为k的满二叉树中编号为1~n的结点一一对应,这棵二叉树称为完全二叉树。
可以根据公式进行推导,假设n0是度为0的结点总数(即叶子结点数),n1是度为1的结点总数,n2是度为2的结点总数,由二叉树的性质可知:n0=n2+1,则n=
n0+n1+n2(其中n为完全二叉树的结点总数),由上述公式把n2消去得:n=
2n0+n1-1,由于完全二叉树中度为1的结点数只有两种可能0或1,由此得到n0=(n+1)/2或n0=n/2,合并成一个公式:n0=(n+1)/2
,就可根据完全二叉树的结点总数计算出叶子结点数。
因此叶子结点数是(839+1)/2=420

二叉树算法

4. 完全二叉树的算法

如果一棵具有n个结点的深度为k的二叉树,它的每一个结点都与深度为k的满二叉树中编号为1~n的结点一一对应,这棵二叉树称为完全二叉树。可以根据公式进行推导,假设n0是度为0的结点总数(即叶子结点数),n1是度为1的结点总数,n2是度为2的结点总数,由二叉树的性质可知:n0=n2+1,则n= n0+n1+n2(其中n为完全二叉树的结点总数),由上述公式把n2消去得:n= 2n0+n1-1,由于完全二叉树中度为1的结点数只有两种可能0或1,由此得到n0=(n+1)/2或n0=n/2。总结起来,就是 n0=[n/2],其中[]表示上取整。可根据完全二叉树的结点总数计算出叶子结点数。

5. python二叉树输出结果为什么是这样

1. 二叉树
二叉树(binary tree)中的每个节点都不能有多于两个的儿子。

1.1 二叉树列表实现
如上图的二叉树可用列表表示:

12345678
tree=['A',  #root      ['B',    #左子树       ['D',[],[]],       ['E',[],[]]],      ['C',     #右子树       ['F',[],[]],       []]      ]

实现:

1234567891011121314151617181920
def BinaryTree(item):    return [item,[],[]]def insertLeft(tree,item):    leftSubtree=tree.pop(1)    if leftSubtree:        tree.insert(1,[item,leftSubtree,[]])    else:        tree.insert(1,[item,[],[]])    return treedef insertRight(tree,item):    rightSubtree=tree.pop(2)    if rightSubtree:        tree.insert(2,[item,[],rightSubtree])    else:        tree.insert(2,[item,[],[]])    return treedef getLeftChild(tree):    return tree[1]def getRightChild(tree):    return tree[2]

要实现下图的树:



123456
tree=BinaryTree('a')insertLeft(tree,'b')insertRight(tree,'c')insertRight((getLeftChild(tree)),'d')insertLeft((getRightChild(tree)),'e')insertRight((getRightChild(tree)),'f')

1.2 二叉树的类实现

12345678910111213141516171819
class BinaryTree(object):    def __init__(self,item):        self.key=item        self.leftChild=None        self.rightChild=None    def insertLeft(self,item):        if self.leftChild==None:            self.leftChild=BinaryTree(item)        else:            t=BinaryTree(item)            t.leftChild=self.leftChild            self.leftChild=t    def insertRight(self,item):        if self.rightChild==None:            self.rightChild=BinaryTree(item)        else:            t=BinaryTree(item)            t.rightChild=self.rightChild            self.rightChild=t

2. 表达式树
表达式树(expression tree)的树叶是操作数,其他节点为操作符。

图   ((7+3)*(5-2))的表达式树表示
2.1 根据中缀表达式构造表达式树:
遍历表达式:
1.建立一个空树
2.遇到'(',为当前的Node添加一个left child,并将left child当做当前Node。
3.遇到数字,赋值给当前的Node,并返回parent作为当前Node。
4.遇到('+-*/'),赋值给当前Node,并添加一个Node作为right child,将right child当做当前的Node。
5.遇到')',返回当前Node的parent。

123456789101112131415161718192021222324
def buildexpressionTree(exp):    tree=BinaryTree('')    stack=[]    stack.append(tree)    currentTree=tree    for i in exp:        if i=='(':            currentTree.insertLeft('')            stack.append(currentTree)            currentTree=currentTree.leftChild        elif i not in '+-*/()':            currentTree.key=int(i)            parent=stack.pop()            currentTree=parent        elif i in '+-*/':            currentTree.key=i            currentTree.insertRight('')            stack.append(currentTree)            currentTree=currentTree.rightChild        elif i==')':            currentTree=stack.pop()        else:            raise ValueError    return tree

上述算法对中缀表达式的写法要求比较繁琐,小括号应用太多,例如要写成(a+(b*c))的形式。
用后缀表达式构建表达式树会方便一点:如果符号是操作数,建立一个单节点并将一个指向它的指针推入栈中。如果符号是一个操作符,从栈中弹出指向两棵树T1和T2的指针并形成一棵新的树,树的根为此操作符,左右儿子分别指向T2和T1.

123456789101112131415
def build_tree_with_post(exp):    stack=[]    oper='+-*/'    for i in exp:        if i not in oper:            tree=BinaryTree(int(i))            stack.append(tree)        else:            righttree=stack.pop()            lefttree=stack.pop()            tree=BinaryTree(i)            tree.leftChild=lefttree            tree.rightChild=righttree            stack.append(tree)    return stack.pop()

3.树的遍历
3.1 先序遍历(preorder travelsal)
先打印出根,然后递归的打印出左子树、右子树,对应先缀表达式

12345678
def preorder(tree,nodelist=None):    if nodelist is None:        nodelist=[]    if tree:        nodelist.append(tree.key)        preorder(tree.leftChild,nodelist)        preorder(tree.rightChild,nodelist)    return nodelist


3.2 中序遍历(inorder travelsal)
先递归的打印左子树,然后打印根,最后递归的打印右子树,对应中缀表达式

12345
def inorder(tree):    if tree:        inorder(tree.leftChild)        print tree.key        inorder(tree.rightChild)

3.3 后序遍历(postorder travelsal)
递归的打印出左子树、右子树,然后打印根,对应后缀表达式

1234567
def postorder(tree):    if tree:        for key in postorder(tree.leftChild):            yield key        for key in postorder(tree.rightChild):            yield key        yield tree.key

3.4 表达式树的求值

1234567891011
def postordereval(tree):    operators={'+':operator.add,'-':operator.sub,'*':operator.mul,'/':operator.truediv}    leftvalue=None    rightvalue=None    if tree:        leftvalue=postordereval(tree.leftChild)        rightvalue=postordereval(tree.rightChild)        if leftvalue and rightvalue:            return operators[tree.key](leftvalue,rightvalue)        else:            return tree.key

python二叉树输出结果为什么是这样

6. 二叉树算法是什么?

二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。
二叉树的第i层至多有2^(i 1)个结点;深度为k的二叉树至多有2^k 1个结点;对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0 = n2 + 1。二叉树算法常被用于实现二叉查找树和二叉堆。
二叉树是每个节点最多有两个子树的有序树。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

扩展资料:
二叉树也是递归定义的,其结点有左右子树之分,逻辑上二叉树算法有五种基本形态:
1、空二叉树——(a)
2、只有一个根结点的二叉树——(b);
3、右子树为空的二叉树——(c);
4、左子树为空的二叉树——(d);
5、完全二叉树——(e)
注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。

7. 二叉树算法是什么?

二叉树是每个节点最多有两个子树的有序树。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。



性质
1、在二叉树中,第i层的结点总数不超过2^(i-1)。
2、深度为h的二叉树最多有2^h-1个结点(h>=1),最少有h个结点。
3、对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1。

二叉树算法是什么?

8. 最优二叉树算法的基本概念

最优二叉树,也称哈夫曼(Haffman)树,是指对于一组带有确定权值的叶结点,构造的具有最小带权路径长度的二叉树。那么什么是二叉树的带权路径长度呢?在前面我们介绍过路径和结点的路径长度的概念,而二叉树的路径长度则是指由根结点到所有叶结点的路径长度之和。如果二叉树中的叶结点都具有一定的权值,则可将这一概念加以推广。设二叉树具有n个带权值的叶结点,那么从根结点到各个叶结点的路径长度与相应结点权值的乘积之和叫做二叉树的带权路径长度,记为:WPL=  Wk·Lk其中Wk为第k个叶结点的权值,Lk 为第k个叶结点的路径长度。如图7.2所示的二叉树,它的带权路径长度值WPL=2×2+4×2+5×2+3×2=28。在给定一组具有确定权值的叶结点,可以构造出不同的带权二叉树。例如,给出4个叶结点,设其权值分别为1,3,5,7,我们可以构造出形状不同的多个二叉树。这些形状不同的二叉树的带权路径长度将各不相同。图7.3给出了其中5个不同形状的二叉树。这五棵树的带权路径长度分别为:(a)WPL=1×2+3×2+5×2+7×2=32(b)WPL=1×3+3×3+5×2+7×1=29(c)WPL=1×2+3×3+5×3+7×1=33(d)WPL=7×3+5×3+3×2+1×1=43(e)WPL=7×1+5×2+3×3+1×3=29最优二叉树算法  最优二叉树算法由此可见,由相同权值的一组叶子结点所构成的二叉树有不同的形态和不同的带权路径长度,那么如何找到带权路径长度最小的二叉树(即哈夫曼树)呢?根据哈夫曼树的定义,一棵二叉树要使其WPL值最小,必须使权值越大的叶结点越靠近根结点,而权值越小的叶结点越远离根结点。哈夫曼(Haffman)依据这一特点于1952年提出了一种方法,这种方法的基本思想是:(1)由给定的n个权值{W1,W2,…,Wn}构造n棵只有一个叶结点的二叉树,从而得到一个二叉树的集合F={T1,T2,…,Tn};(2)在F中选取根结点的权值最小和次小的两棵二叉树作为左、右子树构造一棵新的二叉树,这棵新的二叉树根结点的权值为其左、右子树根结点权值之和;(3)在集合F中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入到集合F中;(4)重复(2)(3)两步,当F中只剩下一棵二叉树时,这棵二叉树便是所要建立的哈夫曼树。