算法导论 python代码 第十二章

深入理解二叉搜索树
本文详细介绍了二叉搜索树的节点定义、遍历方法、查找、插入、删除等核心操作,提供了完整的Python代码实现。
# author Ttssxuan
# chapter 12
# the binary search tree

class Node:
    '''
    the node of the binary tree

    Properties:
        p - the parent of the current node
        left - the left child of the current node
        right - the right child of the current node
        value - the value of this node
    '''
    def __init__(self):
        self.p = None
        self.left = None
        self.right = None
        self.value =  None
    def __init__(self, other):
        self.p = other.p
        self.left = other.left
        self.right = other.right
        self.value = other.value
    def __str__(self):
        return str(self.value)

def inorder_tree_walk(x):
    '''
    scan all keys by inorder tree walk method

    Parameters:
        x - the root of the binary search tree
    Returns:
        none
    '''
    if x != None:
        inorder_tree_walk(x.left)
        print(x + " ")
        inorder_tree_walk(x.right)

def interative_inorder_tree_wal(x):
    '''
    12.1.3
    scan all keys by inorder tree walk method with nonrecursive

    Parameters:
        x - the root of the binary search tree
    Returns:
        none
    '''
    done = False
    cur = Node(x)
    stack = []
    while(done):
        if cur != None:
            stack.append(cur)
            cur = cur.left
        else:
            if len(stack) > 0:
                cur = stack.pop()
                print(cur + " ")
                cur = cur.right
            else:
                done = True

def preorder_tree_walk(x):
    '''
    12.1.4
    scan all keys by preorder tree walk method

    Parameters:
        x - the root of the binary search tree
    Returns:
        none
    '''
    if x != None:
        print(x + " ")
        preorder_tree_walk(x.left)
        preorder_tree_walk(x.right)

def postorder_tree_walk(x):
    '''
    12.1.4
    scan all keys by postorder tree walk method

    Parameters:
        x - the root of the binary search tree
    Returns:
        none
    '''
    if x != None:
        postorder_tree_walk(x)
        postorder_tree_walk(x)
        print(x + " ")

def tree_search(x, k):
    '''
    12.2
    search the given key of the binary search tree

    Parameters:
        x - the root of the binary search tree
        k - the key need to search
    Returns:
        the node that contains the k
    '''
    if x == None or k == x.value:
        return x
    if k < x.value:
        return tree_search(x.left, k)
    else:
        return tree_search(x.right, k)

def interative_tree_search(x, k):
    '''
    12.2
    the unrolling version of searching the binary search tree

    Parameters:
        x - the root of the binary search tree
        k - the key need to search
    Returns:
        the node that contains the k
    '''
    while x != None and k != x.value:
        if k < x.value:
            x = x.left
        else:
            x = x.right
    return x

def tree_minimum(x):
    '''
    12.2
    find the minimum key of the binary search tree

    Parameters:
        x - the root of the binary search tree
    Returns:
        the node that contains the minimum key 
    '''
    if x == None:
        return None
    while x.left != None:
        x = x.left
    return x

def tree_maximum(x):
    '''
    12.2
    find the maximum key of the binary search tree

    Parameters:
        x - the root of the binary search tree
    Returns:
        the node that contains the maximum key
    '''
    if x == None:
        return None
    while x.right != None:
        x = x.right
    return x

def tree_successor(x):
    '''
    12.2
    find the successor of the given node

    Parameters:
       x - the node need to find the successor
    Returns:
        the node which contains the successor of x
    '''
    if x.right != None:
        return tree_minimum(x.right)
    y = x.p
    while y != None and x == y.right:
        x = y
        y = y.p
    return None

def tree_predecessor(x):
    '''
    12.2.3
    find the predecessor of the given node

    Parameters:
        x - the node need to find the predecessor
    Returns:
        the node whick contains the predecessor of x
    '''
    if x.left != None:
        return tree_maximum(x.left)
    return x.p

def tree_insert(t, x):
    '''
    12.3
    insert the given node into the binary search tree

    Parameters:
        t - the given binary search tree
        x - the node needs to insert into the binary search tree
    Returns:
        none
    '''
    y = None
    x = t.root
    while x != None:
        y = x
        if z.value < x.value:
            x = x.left
        else:
            x = x.right
    z.p = y
    if y == None:
        t.root = z
    elif z.key < y.key:
        y.left = z
    else:
        y.right = z


def transplant(t, u, v):
    '''
    move subtrees around within the binary search tree

    Parameters:
        t - the given binary tree
        u - the subtree was to be replaced
        v - the subtree used to replacing the subtree u
    Return:
        None
    '''
    if u.p == None:
        t.root = v
    elif u == u.p.left:
        u.p.left = v
    else:
        u.p.right = v
    if v != None:
        v.p = u.p

def tree_delete(t, z):
    '''
    delete the given node z which belongs to the tree t
    '''
    if z.left == None:
        transplant(t, z, z.right)
    elif z.right == None:
        transplant(t, z, z.left)
    else:
        y = tree_minimum(z.right)
        if y.p != z:
            transplant(t, y, y.right)
            y.right = z.right
            y.right.p = y
        transplant(t, z, y)
        y.left = z.left
        y.left.p = y

### 关于《算法导论》第16章的答案解析 《算法导论》第16章主要讨论的是贪心算法及其应用。这一章节的内容涵盖了如何设计和验证贪心策略的有效性,以及一些经典的贪心算法案例,比如活动选择问题、霍夫曼编码等[^1]。 对于具体的习题解答,《算法导论》提供了详细的解析过程来帮助读者更好地理解和掌握这些概念。以下是关于第16章的一些典型题目解析: #### 贪心算法的核心思想 贪心算法是一种在每一步都做出局部最优选择的算法设计方法,其目标是通过一系列这样的选择达到全局最优解。然而,并非所有问题都可以用贪心法求解,因此需要严格证明所选策略能够保证最终结果是最优的[^1]。 #### 经典例子——活动选择问题 活动选择问题是典型的可以采用贪心算法解决的问题之一。给定一组相互冲突的活动集合S={a₁,a₂,...,an},其中每个活动ai都有一个开始时间和结束时间(si,fi),我们的任务是从这个活动中选出最大的兼容子集A⊆S。这里的关键在于按照最早完成时间排序后依次挑选不重叠的任务加入到解决方案当中去[^1]。 ```python def greedy_activity_selector(s, f): n = len(f) A = [] i = 0 A.append(i) for m in range(1, n): if s[m] >= f[i]: A.append(m) i = m return A ``` 此函数实现了基于上述原理的选择逻辑[^1]。 #### 另一个重要主题——霍夫曼编码 霍夫曼编码利用字符频率构建一棵带权路径长度最小化的二叉树来进行数据压缩处理。它同样遵循着一种特定形式上的贪婪准则,在整个过程中不断选取当前具有最低概率值的一对节点组合成新的父节点直到只剩下一个根为止。 ```python import heapq from collections import defaultdict class NodeTree(object): def __init__(self, left=None, right=None): self.left = left self.right = right def children(self): return (self.left, self.right) def huffman_code_tree(node, binString=''): if type(node) is str: return {node: binString} (l, r) = node.children() d = dict() d.update(huffman_code_tree(l, binString + '0')) d.update(huffman_code_tree(r, binString + '1')) return d freq = {'a': 45, 'b': 13, 'c': 12, 'd': 16, 'e': 9, 'f': 5} heap = [[weight, [symbol, ""]] for symbol, weight in freq.items()] heapq.heapify(heap) while len(heap) > 1: lo = heapq.heappop(heap) hi = heapq.heappop(heap) for pair in lo[1:]: pair[-1] = '0' + pair[-1] for pair in hi[1:]: pair[-1] = '1' + pair[-1] heapq.heappush(heap, [lo[0]+hi[0]] + lo[1:] + hi[1:]) hc = sorted(heapq.heappop(heap)[1:], key=lambda p: (len(p[-1]),p)) print("Symbol".ljust(10) + "Frequency".ljust(10) + "Huffman Code") for p in hc: print(p[0].ljust(10)+str(freq[p[0]]).ljust(10)+p[1]) ``` 这段代码展示了如何根据输入字母表创建相应的霍夫曼编码方案[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值