二叉树相关算法

一、遍历

先根序(前序遍历) 

 def ergodic(root):
    if root is None:
        return
    proc(root.val)
    ergodic(root.left)
    ergodic(root.right)
def ergodic(root):
    s = Stack()
    while root is not None or not s.is_empty():
        while root is not None:
            proc(root.val)
            s.push(root.right)
            root = root.left
        root = s.pop()

中根序

def ergodic(root):
    if root is None:
        return
    ergodic(root.left)
    proc(root.val)
    ergodic(root.right)
def ergodic(root):
    s = Stack()
    while root is not None or not s.is_empty():
        while root is not None:
            s.push(root)
            root = root.left
        root = s.pop()
        proc(root.val)
        root = root.right

后根序

def ergodic(root):
    is root is None:
        return 
    ergodic(root.left)
    ergodic(root.right)
    proc(root.val)
def ergodic(root):
    s = Stack()
    while root is not None or not s.is_empty():
        while root is not None:
            s.push(root)
            root = root.left if root.left is not None else root.right
        root = s.pop()
        proc(root.val)
        if not s.is_empty() and s.top().left == root:
            root = s.top().right
        else:
            root = None

宽度优先遍历

def ergodic(root):
    q = Queue()
    q.enqueue(root)
    while not q.is_empty():
        root = q.dequeue()
        proc(root.val)
        if not root.left is None:
            q.enqueue(root.left)
        if not root.right is None:
            q.enqueue(root.right)
def ergodic(root):
    if root is None:
        return []
    q = []
    ans = []
    q.append(root)
    while len(q) != 0:
        length = len(q)
        ans.append([])
        for i in range(length):
            node = q[0]
            del q[0]
            ans[-1].append(node.val)
            if not node.left is None:
                q.append(node.left)
            if not node.right is None:
                q.append(node.right)

二、回溯

def traverse(root, sum, path, res):
    if root is None:
        return
    path.append(root.val)
    if root.left is None and root.right is None:
        if root.val == sum:
            res.append(path)
    
    target = sum - root.val
    traverse(root.left, target, path, res)
    traverse(root.right, target, path, res)
    del path[-1]

三、根据序列建树

根据前序遍历与中序遍历建树

class Node:
    def __init__(self, val = None, left = None, right = None):
        self.val = val
        self.left = left
        self.right = right


def build_pre_mid(pre, pre1, pre2, mid, mid1, mid2):
    if pre1 > pre2:
        return None
    rootval = pre[pre1]
    index = 0
    for i in range(mid1, mid2 + 1):
        if mid[i] == rootval:
            index = i
            break
    leftsize = index - mid1
    root = Node(rootval)
    root.left = build_pre_mid(pre, pre1 + 1, pre1 + leftsize, mid, mid1, index - 1)
    root.right = build_pre_mid(pre, pre1 + leftsize + 1, pre2, mid, index + 1, mid2)
    return root



def print_tree(root):
    if root is None:
        print("^", end='')
        return
    print("("+str(root.val), end='')
    print_tree(root.left)
    print_tree(root.right)
    print(")", end='')


a = list(map(int, input().split(' ')))
b = list(map(int, input().split(' ')))


print_tree(build_pre_mid(a, 0, len(a)-1, b, 0, len(b)-1))

根据中序遍历与后序遍历建树

class Node:
    def __init__(self, val = None, left = None, right = None):
        self.val = val
        self.left = left
        self.right = right


def build_mid_post(mid, mid1, mid2, post, post1, post2):
    if mid1 > mid2:
        return None
    rootval = post[post2]
    index = 0
    for i in range(mid1, mid2 + 1):
        if mid[i] == rootval:
            index = i
            break
    leftsize = index - mid1
    root = Node(rootval)
    root.left = build_mid_post(mid, mid1, index - 1, post, post1, post1 + leftsize - 1)
    root.right = build_mid_post(mid, index + 1, mid2, post, post1 + leftsize, post2 - 1)
    return root



def print_tree(root):
    if root is None:
        print("^", end='')
        return
    print("("+str(root.val), end='')
    print_tree(root.left)
    print_tree(root.right)
    print(")", end='')


a = list(map(int, input().split(' ')))
b = list(map(int, input().split(' ')))


print_tree(build_mid_post(a, 0, len(a)-1, b, 0, len(b)-1))

四、线索树

4.1        先序线索化二叉树

def preorder(root):
    s = Stack()
    last = None
    if root is None:
        return
    s.push(root)
    while not s.is_empty():
        p = s.pop()
        if p.left is None:
            p.lt = 1
            p.left = last
        if last is not None:
            if last.right is None:
                last.rt = 1
                last.right = p
        last = p
        if p.right is not None and p.rt == 0:
            s.push(p.right)
        if p.left is not None and p.lt == 0:
            s.push(p.left)
    last.rt = 1

4.2        中序线索化二叉树

def inorder(root):
    s = Stack()
    last = None
    p = root
    while p is not None or not s.is_empty():
        if p is not None:
            s.push(p)
            p = p.left
        else:
            p = s.pop()
            if p.left is None:
                p.lt = 1
                p.left = last
            if last is not None:
                if last.right is None:
                    last.rt = 1
                    last.right = p
            last = p
            p = p.right
    last.rt = 1

4.3        先序遍历线索二叉树

def preorder_bt(root):
    p = root
    arr = []
    while p is not None:
        arr.append(p.val)
        if p.lt == 0:
            p = p.left
        else:
            p = p.right
    print(arr)

4.4        中序遍历线索二叉树

def inorder_bt(root):
    p = root
    arr = []
    while p is not None and p.lt == 0:
        p = p.left
    while p is not None:
        arr.append(p.val)
        if p.rt == 1:
            p = p.right
        else:
            p = p.right
            while p is not None and p.lt == 0:
                p = p.left
    print(arr)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值