繁体   English   中英

使用 Python 中的字典构建二叉搜索树

[英]Build binary search tree using dictionary in Python

我正在尝试在 python 中使用 dict 构建 BST(二叉搜索树)。 我不明白为什么我的代码没有向 BST 添加节点。 我在这里看到了一个类似的帖子: 如何在 Python 中实现二叉搜索树? 除了声明一个节点 class 之外,它看起来与我的代码相同,但我想知道为什么我的 dict 实现失败(并希望提高我对在 python 中使用递归传递参数的理解)。

keys = [10,9,2,5,3,7,101,18]
start = {'key': keys[-1], 'val': 1, 'left': None, 'right': None}
def binarySearch(root, node):
# compare keys and insert node into right place
    if not root:
        root = node
    elif node['key'] < root['key']:
        binarySearch(root['left'], node)
    else:
        binarySearch(root['right'], node)

# Now let's test our function and build a BST
while keys:
    key = keys.pop()
    node = {'key': key, 'val': 1, 'left': None, 'right': None}
    binarySearch(start, node)
print(start) # unchanged, hence my confusion. Thx for your time!

============================================

编辑:这是使它工作的代码!

def binarySearch(root, node):
# compare keys and insert node into right place
    if not root:
        root = node
    elif node['key'] < root['key']:
        if not root['left']: root['left'] = node
        else: binarySearch(root['left'], node)
    else:
        if not root['right']: root['right'] = node
        else: binarySearch(root['right'], node)

这是我认为在幕后发生的事情(为什么一个版本能够添加到 BST 而另一个版本不能):

在原始版本中,我们将到达一个递归调用,其中root仍然指向 BST 内部的 None,但随后root = node使root指向与start绝对没有连接的node ,即 BST 本身。 然后局部变量被删除并且不做任何改变。

在修改后的版本中,我们将避免这种情况,因为当我们通过例如root['left'] = node添加节点时。 这里root仍然指向原始 BST,因此我们正在修改原始 BST 中的 key-val 对,而不是让root指向完全在 BST 之外的东西。

让我们像 python 解释器一样运行您的代码。

让我们从第一次调用开始: binarySearch(start, node)

这里start是在脚本顶部定义的dict ,而node是另一个dict (奇怪的是它具有相同的值)。

让我们跳入调用,我们发现自己在: if not root:其中root指的是上面的start ,所以是truthy ,所以if失败了。

接下来我们发现自己在: elif node['key'] < root['key']:在这种情况下不是True

接下来我们传递到else:我们在: binarySearch(root['right'], node)

就在我们跳入第一个递归调用之前,让我们回顾一下调用的参数是什么:从startroot['right']的值为None并且node仍然是我们想要插入某处的同一个dict 因此,进入递归调用。

我们再次发现自己处于: if not root:

然而这次root只是指第一个递归调用的第一个参数,我们可以从上面对参数的回顾中看到root指的是None

现在None被认为是falsy的,所以这次if成功了,我们进入下一行。

现在我们在root = node

这是 python 中的分配。 这意味着 python 将使用变量root停止引用None并引用当前引用的任何node ,这是在while循环中创建的dict 所以root (这只是一个参数,但你现在可以将其视为局部变量)指的是dict

现在发生的事情是我们在第一个递归调用的末尾,这个 function 结束了。 每当 function 结束时,所有局部变量都会被销毁。 rootnode被破坏。 那只是这些变量,而不是它们所指的内容。

现在我们回到第一个调用站点之后,即在binarySearch(root['right'], node)之后

我们可以在这里看到参数: root['right'], node仍然引用它们之前引用的任何内容。 这就是为什么你的start没有改变以及为什么你的程序应该right处理left而不是递归的原因。

#Creted by The Misunderstood Genius
def add_root(e,key):
    ''''
     e is node's name
    key is the node's key search
    '''
    bst=dict()
    bst[e]={'key':key,'P':None,'L':None,'R':None}
    return bst
def root(tree):
   for k,v in tree.items():
       if v['P'] == None:
           return k





def insert(tree, node, key):
    tree[node]={'key':key,'P':None,'L':None,'R':None}
    y =None
    x = root(tree)
    node_key = tree[node]['key']
    while x is not None:
        y=x
        node_root=tree['R']['key']
        if node_key < node_root:
            x=tree[x]['L']
        else:
            x=tree[x]['R']
    tree[node]['P']=y
    if y is not None and node_key< tree[y]['key']:
        tree[y]['L']=node
    else:
        tree[y]['R']=node

    return  tree


def print_all(tree):
   for k,v in tree.items():
       print(k,v)
       print()
'''
Give a root node and key search target 
Returns the name of the node with associated key 
Else None
'''
def tree_search(tree,root, target):
    if root ==None:
        print(" key with node associate not found")
        return root
    if tree[root]['key'] == target:
        return  root
    if target < tree[root]['key']:
        return tree_search(tree,tree[root]['L'],target)
    else:
        return  tree_search(tree,tree[root]['R'],target)

def tree_iterative_search(tree,root,target):


    while root is not  None and tree[root]['key']!=target:

        if target < tree[root]['key']:
            root=tree[root]['L']


        else:
            root=tree[root]['R']


    return root

def minimum(tree,root):
    while tree[root]['L'] is not None:
        root=tree[root]['L']
    return tree[root]['key']






bst=add_root('R',20)

bst=insert(bst,'M',10)
bst=insert(bst,'B',8)
bst=insert(bst,'C',24)
bst=insert(bst,'D',22)
bst=insert(bst,'E',25)
bst=insert(bst,'G',25)
print_all(bst)
print(tree_search(bst,'R',25))
x=tree_iterative_search(bst,'R',25)
print(x)
#print(minimum(bst,'R'))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM