Python版算法实战-二叉树

发布于:2022-12-15 ⋅ 阅读:(1136) ⋅ 点赞:(1)

视频讲解

 树的概念

        树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构, 用来模拟具有树状结构性质的数据集合。它是由 n(n>=1)个有限节点组成一个具有层次关 系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:

        (1) 每个节点有零个或多个子节点;

        (2) 没有父节点的节点称为根节点;

        (3) 每一个非根节点有且只有一个父节点;

        (4) 除了根节点外,每个子节点可以分为多个不相交的子树;

树的术语

(1) 节点的度:一个节点含有的子树的个数称为该节点的度;

(2) 树的度:一棵树中,最大的节点的度称为树的度;

(3) 叶节点或终端节点:度为零的节点;

(4) 父亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;

(5) 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;

(6) 兄弟节点:具有相同父节点的节点互称为兄弟节点;

(7) 节点的层次:从根开始定义起,根为第 1 层,根的子节点为第 2 层,以此类推;

(8) 树的高度或深度:树中节点的最大层次;

(9) 堂兄弟节点:父节点在同一层的节点互为堂兄弟;

(10)节点的祖先:从根到该节点所经分支上的所有节点;

(11)子孙:以某节点为根的子树中任一节点都称为该节点的子孙。

(12)森林:由 m(m>=0)棵互不相交的树的集合称为森林;

二叉树的基本概念

        二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree) 和“右子树”(right

二叉树的性质

        性质 1: 在二叉树的第 i 层上至多有 2^(i-1)个节点(i>0)

        性质 2: 深度为 k 的二叉树至多有 2^k - 1 个节点(k>0)

        性质 3: 对于任意一棵二叉树,如果其叶节点数为 N0,而度数为 2 的结点总数为 N2, 则 N0=N2+1;

        性质 4:具有 n 个节点的完全二叉树的深度必为 log2(n+1)

        性质 5:对完全二叉树,若从上至下、从左至右编号,则编号为 i 的结点,其左孩子编 号必为 2i,其右孩子编号必为 2i+1;其双亲的编号必为 i/2(i=1 时为根,除外)

代码

1.n个二叉树的节点

'''n个二叉树的节点'''

def count(n):
    # root : 1
    # left : k   0 <= k <= n-1
    # right: n-1-k
    s = count.cache.get(n,0)
    if s:
        return s
    for k in range(n):
        print('ok')
        s += count(k) * count(n - 1 - k)
    count.cache[n] = s
    return s
count.cache = {0: 1}
print(count(5))

2.创建一个二叉树

'''构建一个二叉树'''

class TreeNode(object):
    def __init__(self, data, left = None, right = None): # data为数据 left为左分支,不传参数默认为None right为右分支,不传参数默认为None
        self.data = data
        self.left = left
        self.right = right
#两种创建一个简单的二叉树的方式 假设二叉树为ABC
#第一种
B = TreeNode('B')
C = TreeNode('C')
A = TreeNode('A')
root = A
#第二种
A.left = B
A.right = C

#创建一个复杂的二叉树
A,B,C,D,E,F,G,H,I = [TreeNode(x) for x in 'ABCDEFGHI']
A.left = B
A.right = C
B.right = D
C.left = E
C.right = F
E.left = G
F.left = H
F.right = I

print(C.left.data)

3.遍历二叉树(递归版)

        先序遍历,根左右
        中序遍历,左根右
        后序遍历,左右根

'''
先序遍历,根左右
中序遍历,左根右
后序遍历,左右根
'''
import sys
sys.setrecursionlimit(100000) #例如这里设置为十万

class TreeNode(object):
    def __init__(self,data, left = None, right = None): # data为数据 left为左分支,不传参数默认为None right为右分支,不传参数默认为None
        self.data = data
        self.left = left
        self.right = right

    def __repr__(self):
        return str(self)
#创建一个复杂的二叉树
def creattreenode():
    A,B,C,D,E,F,G,H,I = [TreeNode(x) for x in 'ABCDEFGHI']
    A.left = B
    A.right = C
    B.right = D
    C.left = E
    C.right = F
    E.left = G
    F.left = H
    F.right = I
    return A  #返回根节点

#递归版遍历二叉树(node)为访问二叉树的根节点
#先序遍历
def preorder(node):
    if node is None:
        return
    print(node.data)
    preorder(node.left)
    preorder(node.right)


#中序遍历
def inorder(node):
    if node is None:
        return

    preorder(node.left)
    print(node.data)
    preorder(node.right)


#后续遍历
def postorder(node):
    if node is None:
        return

    preorder(node.left)
    preorder(node.right)
    print(node.data)



#迭代版本先序遍历(回溯法)
def preorderiter(node):
    s = []
    while True:
        while node:
            print(node)
            s.append(node)
            node = node.left
        if not s:
            break
        node = s.pop().right


#层序遍历
from collections import deque
def levelorder(node):
    q = deque([node])
    while q:
        node = q.popleft()
        print(node)
    
        if node.left:
            q.append(node.left)
        if node.right:
            q.append(node.right)



pn = creattreenode()

# preorder(pn)
levelorder(pn)

4.二叉树的深度 

#二叉树的深度(递归的方式)
def depth(node):
    if node is None:
        return 0
    dl = depth(node.left)
    dr = depth(node.right)
    result = max(dl, dr) + 1
    return  result

# 二叉树的深度(非递归,层序遍历)
from collections import deque
def depth2(node):
    q = deque([(node, 1)])
    while q :
        node, d = q.popleft()

        if node.left:
            q.append((node.left, d + 1))
        if node.right:
            q.append((node.right, d + 1))

    return d

5.拷贝二叉树

def copytree(node):
    if node is None:
        return None
    lt = copytree(node.left)
    rt = copytree(node.right)

    root = TreeNode(node.data, lt , rt)
    return root

6.二叉树的操作(搜索,插入,删除)

class searchtree():
    def __init__(self):
        self.root = None

    def search(self,k):
        node, _ = self._search(k)
        return node
    def _search(self,k):
        parent = None
        node = self.root
        while node and node.data != k:
            parent = node
            if k < node.data:
                node = node.left
            else:
                node = node.right
        return node, parent

    def insert(self,k):
        node, parent = self._search(k)
        if node:
            return
        node = TreeNode(k)
        if parent is None:
            self.root = node
        elif k< parent.data:
            parent.left = node
        else:
            parent.right = node
    def delete(self,k):
        pass


网站公告

今日签到

点亮在社区的每一天
去签到