Πώς να εφαρμόσει ένα δυαδικό δέντρο αναζήτησης σε Python;

ψήφοι
25

Αυτό είναι ό, τι έχω μέχρι τώρα, αλλά δεν λειτουργεί:

class Node:
    rChild,lChild,data = None,None,None

    def __init__(self,key):
        self.rChild = None
        self.lChild = None
        self.data = key

class Tree:
    root,size = None,0
    def __init__(self):
        self.root = None
        self.size = 0

    def insert(self,node,someNumber):
        if node is None:
            node = Node(someNumber)
        else:
            if node.data > someNumber:
                self.insert(node.rchild,someNumber)
            else:
                self.insert(node.rchild, someNumber)
        return

def main():
    t = Tree()
    t.root = Node(4)
    t.root.rchild = Node(5)
    print t.root.data #this works
    print t.root.rchild.data #this works too
    t = Tree()
    t.insert(t.root,4)
    t.insert(t.root,5)
    print t.root.data #this fails
    print t.root.rchild.data #this fails too

if __name__ == '__main__':
     main()
Δημοσιεύθηκε 26/03/2011 στις 19:37
πηγή χρήστη
Σε άλλες γλώσσες...                            


17 απαντήσεις

ψήφοι
5

Το ΕΠ της Tree.insertμεθόδου πληροί τις προϋποθέσεις για την «Ακαθάριστη ψευδεπίγραφος της Εβδομάδας» βραβείο - δεν εισέρχεται τίποτα. Δημιουργεί ένα κόμβο ο οποίος δεν συνδέεται με οποιοδήποτε άλλο κόμβο (όχι ότι υπάρχουν κόμβοι για να επισυνάψετε) και στη συνέχεια το δημιούργησε κόμβος πατήθηκε όταν η μέθοδος επιστρέφει.

Για την οικοδόμηση της @Hugh Bothwell:

>>> class Foo(object):
...    bar = None
...
>>> a = Foo()
>>> b = Foo()
>>> a.bar
>>> a.bar = 42
>>> b.bar
>>> b.bar = 666
>>> a.bar
42
>>> b.bar
666
>>>
Απαντήθηκε 26/03/2011 στις 19:50
πηγή χρήστη

ψήφοι
9
class Node: 
    rChild,lChild,data = None,None,None

Αυτό είναι λάθος - να το κάνει μεταβλητές σας μεταβλητές τάξης - δηλαδή, κάθε εμφάνιση του κόμβου χρησιμοποιεί τις ίδιες τιμές (αλλαγή rChild οποιουδήποτε κόμβου αλλάζει για όλους τους κόμβους!). Αυτό είναι προφανώς δεν είναι αυτό που θέλετε? προσπαθήστε

class Node: 
    def __init__(self, key):
        self.rChild = None
        self.lChild = None
        self.data = key

τώρα κάθε κόμβος έχει το δικό του σύνολο των μεταβλητών. Το ίδιο ισχύει και για το δικό σας ορισμό των δέντρων,

class Tree:
    root,size = None,0    # <- lose this line!
    def __init__(self):
        self.root = None
        self.size = 0

Επιπλέον, κάθε τάξη θα πρέπει να είναι μια κατηγορία «νέου τύπου» που προέρχεται από την κατηγορία «αντικείμενο» και θα πρέπει αλυσίδα πίσω στην αντιρρήσεις .__ init __ ():

class Node(object): 
    def __init__(self, data, rChild=None, lChild=None):
        super(Node,self).__init__()
        self.data   = data
        self.rChild = rChild
        self.lChild = lChild

class Tree(object):
    def __init__(self):
        super(Tree,self).__init__()
        self.root = None
        self.size = 0

Επίσης, main () είναι σε εσοχή πολύ μακριά - όπως φαίνεται, είναι μια μέθοδος Δέντρο που είναι uncallable επειδή δεν αποδέχεται μια αυτο το επιχείρημα.

Επίσης, θα έχετε την τροποποίηση των δεδομένων του αντικειμένου απ 'ευθείας ( t.root = Node(4)), η οποία είδος καταστρέφει ενθυλάκωσης (το νόημα της ύπαρξης τάξεων στην πρώτη θέση)? θα πρέπει να κάνει κάτι περισσότερο σαν

def main():
    t = Tree()
    t.add(4)    # <- let the tree create a data Node and insert it
    t.add(5)
Απαντήθηκε 26/03/2011 στις 20:01
πηγή χρήστη

ψήφοι
1

Απλά κάτι για να σας βοηθήσει να ξεκινήσετε την.

Ένα (απλή ιδέα) δυαδική αναζήτηση δέντρο θα είναι αρκετά πιθανό να εφαρμόσουν python σύμφωνα με τις γραμμές:

def search(node, key):
    if node is None: return None  # key not found
    if key< node.key: return search(node.left, key)
    elif key> node.key: return search(node.right, key)
    else: return node.value  # found key

Τώρα το μόνο που χρειάζεται για την υλοποίηση της σκαλωσιάς (δημιουργία δέντρο και ένθετα αξία) και είστε έτοιμοι.

Απαντήθηκε 26/03/2011 στις 20:12
πηγή χρήστη

ψήφοι
45

Εδώ είναι ένα γρήγορο παράδειγμα ενός δυαδικού ένθετο:

class Node:
    def __init__(self, val):
        self.l_child = None
        self.r_child = None
        self.data = val

def binary_insert(root, node):
    if root is None:
        root = node
    else:
        if root.data > node.data:
            if root.l_child is None:
                root.l_child = node
            else:
                binary_insert(root.l_child, node)
        else:
            if root.r_child is None:
                root.r_child = node
            else:
                binary_insert(root.r_child, node)

def in_order_print(root):
    if not root:
        return
    in_order_print(root.l_child)
    print root.data
    in_order_print(root.r_child)

def pre_order_print(root):
    if not root:
        return        
    print root.data
    pre_order_print(root.l_child)
    pre_order_print(root.r_child)    

r = Node(3)
binary_insert(r, Node(7))
binary_insert(r, Node(1))
binary_insert(r, Node(5))

     3
    / \
   1   7
      /
     5

print "in order:"
in_order_print(r)

print "pre order"
pre_order_print(r)

in order:
1
3
5
7
pre order
3
1
7
5
Απαντήθηκε 26/03/2011 στις 20:35
πηγή χρήστη

ψήφοι
5
class Node:
    rChild,lChild,parent,data = None,None,None,0    

def __init__(self,key):
    self.rChild = None
    self.lChild = None
    self.parent = None
    self.data = key 

class Tree:
    root,size = None,0
    def __init__(self):
        self.root = None
        self.size = 0
    def insert(self,someNumber):
        self.size = self.size+1
        if self.root is None:
            self.root = Node(someNumber)
        else:
            self.insertWithNode(self.root, someNumber)    

    def insertWithNode(self,node,someNumber):
        if node.lChild is None and node.rChild is None:#external node
            if someNumber > node.data:
                newNode = Node(someNumber)
                node.rChild = newNode
                newNode.parent = node
            else:
                newNode = Node(someNumber)
                node.lChild = newNode
                newNode.parent = node
        else: #not external
            if someNumber > node.data:
                if node.rChild is not None:
                    self.insertWithNode(node.rChild, someNumber)
                else: #if empty node
                    newNode = Node(someNumber)
                    node.rChild = newNode
                    newNode.parent = node 
            else:
                if node.lChild is not None:
                    self.insertWithNode(node.lChild, someNumber)
                else:
                    newNode = Node(someNumber)
                    node.lChild = newNode
                    newNode.parent = node                    

    def printTree(self,someNode):
        if someNode is None:
            pass
        else:
            self.printTree(someNode.lChild)
            print someNode.data
            self.printTree(someNode.rChild)

def main():  
    t = Tree()
    t.insert(5)  
    t.insert(3)
    t.insert(7)
    t.insert(4)
    t.insert(2)
    t.insert(1)
    t.insert(6)
    t.printTree(t.root)

if __name__ == '__main__':
    main()

Η λύση μου.

Απαντήθηκε 26/03/2011 στις 21:06
πηγή χρήστη

ψήφοι
6
class BST:
    def __init__(self, val=None):
        self.left = None
        self.right = None
        self.val = val

    def __str__(self):
        return "[%s, %s, %s]" % (self.left, str(self.val), self.right)

    def isEmpty(self):
        return self.left == self.right == self.val == None

    def insert(self, val):
        if self.isEmpty():
            self.val = val
        elif val < self.val:
            if self.left is None:
                self.left = BST(val)
            else:
                self.left.insert(val)
        else:
            if self.right is None:
                self.right = BST(val)
            else:
                self.right.insert(val)

a = BST(1)
a.insert(2)
a.insert(3)
a.insert(0)
print a
Απαντήθηκε 15/08/2012 στις 03:31
πηγή χρήστη

ψήφοι
1

Μια άλλη Python BST με βασικό είδος (αθέτησαν σε αξία)

LEFT = 0
RIGHT = 1
VALUE = 2
SORT_KEY = -1

class BinarySearchTree(object):

    def __init__(self, sort_key=None):
        self._root = []  
        self._sort_key = sort_key
        self._len = 0  

def insert(self, val):
    if self._sort_key is None:
        sort_key = val // if no sort key, sort key is value
    else:
        sort_key = self._sort_key(val)

    node = self._root
    while node:
        if sort_key < node[_SORT_KEY]:
            node = node[LEFT]
        else:
            node = node[RIGHT]

    if sort_key is val:
        node[:] = [[], [], val]
    else:
        node[:] = [[], [], val, sort_key]
    self._len += 1

def minimum(self):
    return self._extreme_node(LEFT)[VALUE]

def maximum(self):
    return self._extreme_node(RIGHT)[VALUE]

def find(self, sort_key):
    return self._find(sort_key)[VALUE]

def _extreme_node(self, side):
    if not self._root:
        raise IndexError('Empty')
    node = self._root
    while node[side]:
        node = node[side]
    return node

def _find(self, sort_key):
    node = self._root
    while node:
        node_key = node[SORT_KEY]
        if sort_key < node_key:
            node = node[LEFT]
        elif sort_key > node_key:
            node = node[RIGHT]
        else:
            return node
    raise KeyError("%r not found" % sort_key)
Απαντήθηκε 29/04/2013 στις 11:25
πηγή χρήστη

ψήφοι
1

Εδώ είναι ένα συμπαγές, αντικειμενοστραφείς, αναδρομική εφαρμογή:

    class BTreeNode(object):
        def __init__(self, data):
            self.data = data
            self.rChild = None
            self.lChild = None

    def __str__(self):
        return (self.lChild.__str__() + '<-' if self.lChild != None else '') + self.data.__str__() + ('->' + self.rChild.__str__() if self.rChild != None else '')

    def insert(self, btreeNode):
        if self.data > btreeNode.data: #insert left
            if self.lChild == None:
                self.lChild = btreeNode
            else:
                self.lChild.insert(btreeNode)
        else: #insert right
            if self.rChild == None:
                self.rChild = btreeNode
            else:
                self.rChild.insert(btreeNode)


def main():
    btreeRoot = BTreeNode(5)
    print 'inserted %s:' %5, btreeRoot

    btreeRoot.insert(BTreeNode(7))
    print 'inserted %s:' %7, btreeRoot

    btreeRoot.insert(BTreeNode(3))
    print 'inserted %s:' %3, btreeRoot

    btreeRoot.insert(BTreeNode(1))
    print 'inserted %s:' %1, btreeRoot

    btreeRoot.insert(BTreeNode(2))
    print 'inserted %s:' %2, btreeRoot

    btreeRoot.insert(BTreeNode(4))
    print 'inserted %s:' %4, btreeRoot

    btreeRoot.insert(BTreeNode(6))
    print 'inserted %s:' %6, btreeRoot

Η έξοδος του ανωτέρω κύρια () είναι:

inserted 5: 5
inserted 7: 5->7
inserted 3: 3<-5->7
inserted 1: 1<-3<-5->7
inserted 2: 1->2<-3<-5->7
inserted 4: 1->2<-3->4<-5->7
inserted 6: 1->2<-3->4<-5->6<-7
Απαντήθηκε 04/09/2013 στις 03:33
πηγή χρήστη

ψήφοι
2

Θεωρώ ότι οι λύσεις είναι λίγο αδέξια στο insertτμήμα. Θα μπορούσε να επιστρέψει την rootαναφορά και την απλούστευση του ένα κομμάτι:

def binary_insert(root, node):
    if root is None:
        return node
    if root.data > node.data:
        root.l_child = binary_insert(root.l_child, node)
    else:
        root.r_child = binary_insert(root.r_child, node)
    return root
Απαντήθηκε 24/09/2014 στις 00:09
πηγή χρήστη

ψήφοι
-1

Εδώ είναι μια εφαρμογή του δείγματος αν αυτό βοηθάει.

Απαντήθηκε 10/11/2015 στις 15:12
πηγή χρήστη

ψήφοι
0

Ο κώδικας που ακολουθεί είναι βασική για την απάντηση @ DTing και ό, τι μαθαίνω από την τάξη, η οποία χρησιμοποιεί ένα βρόχο, ενώ για την εισαγωγή (που αναφέρεται στον κώδικα).

class Node:
    def __init__(self, val):
        self.l_child = None
        self.r_child = None
        self.data = val


def binary_insert(root, node):
    y = None
    x = root
    z = node
    #while loop here
    while x is not None:
        y = x
        if z.data < x.data:
            x = x.l_child
        else:
            x = x.r_child
    z.parent = y
    if y == None:
        root = z
    elif z.data < y.data:
        y.l_child = z
    else:
        y.r_child = z


def in_order_print(root):
    if not root:
        return
    in_order_print(root.l_child)
    print(root.data)
    in_order_print(root.r_child)


r = Node(3)
binary_insert(r, Node(7))
binary_insert(r, Node(1))
binary_insert(r, Node(5))

in_order_print(r)
Απαντήθηκε 08/04/2016 στις 10:19
πηγή χρήστη

ψήφοι
0

Εδώ είναι ένα διάλυμα εργασίας.

class BST:
    def __init__(self,data):
        self.root = data
        self.left = None
        self.right = None

    def insert(self,data):
        if self.root == None:
            self.root = BST(data)
        elif data > self.root:
            if self.right == None:
                self.right = BST(data)
            else:
                self.right.insert(data)
        elif data < self.root:
            if self.left == None:
                self.left = BST(data)
            else:
                self.left.insert(data)

    def inordertraversal(self):
        if self.left != None:
            self.left.inordertraversal()
        print (self.root),
        if self.right != None:
            self.right.inordertraversal()

t = BST(4)
t.insert(1)
t.insert(7)
t.insert(3)
t.insert(6)
t.insert(2)
t.insert(5)
t.inordertraversal()
Απαντήθηκε 24/04/2017 στις 19:22
πηγή χρήστη

ψήφοι
0

εύκολο να εφαρμοστεί ένα BST χρησιμοποιώντας δύο κατηγορίες, 1. Κόμβος και 2. τάξης Δέντρο Δέντρο θα είναι μόνο για διεπαφή χρήστη, και πραγματικές μεθόδους θα εφαρμοστεί σε Κόμβος τάξη.

class Node():

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


    def _insert(self,data):
        if data == self.value:
            return False
        elif data < self.value:
            if self.left:
                return self.left._insert(data)
            else:
                self.left = Node(data)
                return True
        else:
            if self.right:
                return self.right._insert(data)
            else:
                self.right = Node(data)
                return True

    def _inorder(self):
        if self:
            if self.left:
                self.left._inorder()
            print(self.value)
            if self.right:
                self.right._inorder()



class Tree():

    def __init__(self):
        self.root = None

    def insert(self,data):
        if self.root:
            return self.root._insert(data)
        else:
            self.root = Node(data)
            return True
    def inorder(self):
        if self.root is not None:
            return self.root._inorder()
        else:
            return False




if __name__=="__main__":
    a = Tree()
    a.insert(16)
    a.insert(8)
    a.insert(24)
    a.insert(6)
    a.insert(12)
    a.insert(19)
    a.insert(29)
    a.inorder()

Inorder λειτουργία για να ελεγχθεί εάν BST εφαρμόζεται σωστά.

Απαντήθηκε 06/07/2017 στις 08:37
πηγή χρήστη

ψήφοι
0

Η αποδεκτή απάντηση αμελεί να θέσει ένα γονέα χαρακτηριστικού για κάθε κόμβο εισάγεται, χωρίς την οποία δεν μπορεί κανείς να εφαρμόσει μια successorμέθοδο η οποία βρίσκει τον διάδοχο σε ένα in-παραγγελία πόδια δέντρο σε O ( h ) χρόνο, όπου h είναι το ύψος του δέντρου (σε αντιδιαστολή στο O ( n ) χρόνος που απαιτείται για την βόλτα).

Εδώ είναι μια εφαρμογή που βασίζεται στο pseudocode δοθεί στην Cormen et al,. Εισαγωγή στην Αλγόριθμοι , συμπεριλαμβανομένης της κατανομής του parentχαρακτηριστικού και successorμέθοδος:

class Node(object):
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None
        self.parent = None


class Tree(object):
    def __init__(self, root=None):
        self.root = root

    def insert(self, z):
        y = None
        x = self.root
        while x is not None:
            y = x
            if z.key < x.key:
                x = x.left
            else:
                x = x.right
        z.parent = y
        if y is None:
            self.root = z       # Tree was empty
        elif z.key < y.key:
            y.left = z
        else:
            y.right = z

    @staticmethod
    def minimum(x):
        while x.left is not None:
            x = x.left
        return x

    @staticmethod
    def successor(x):
        if x.right is not None:
            return Tree.minimum(x.right)
        y = x.parent
        while y is not None and x == y.right:
            x = y
            y = y.parent
        return y

Εδώ είναι μερικές δοκιμές για να δείξουν ότι το δέντρο συμπεριφέρεται όπως αναμένεται για το παράδειγμα που δίνεται από DTing :

import pytest

@pytest.fixture
def tree():
    t = Tree()
    t.insert(Node(3))
    t.insert(Node(1))
    t.insert(Node(7))
    t.insert(Node(5))
    return t

def test_tree_insert(tree):
    assert tree.root.key == 3
    assert tree.root.left.key == 1
    assert tree.root.right.key == 7
    assert tree.root.right.left.key == 5

def test_tree_successor(tree):
    assert Tree.successor(tree.root.left).key == 3
    assert Tree.successor(tree.root.right.left).key == 7

if __name__ == "__main__":
    pytest.main([__file__])
Απαντήθηκε 25/08/2017 στις 10:42
πηγή χρήστη

ψήφοι
0

Το πρόβλημα, ή τουλάχιστον ένα πρόβλημα με τον κωδικό σας εδώ: -

def insert(self,node,someNumber):
    if node is None:
        node = Node(someNumber)
    else:
        if node.data > someNumber:
            self.insert(node.rchild,someNumber)
        else:
            self.insert(node.rchild, someNumber)
    return

Βλέπετε τη δήλωση «εάν node.data> someNumber:» και το σχετικό «άλλο:» δήλωση οι δύο έχουν τον ίδιο κωδικό μετά από αυτές. δηλαδή να κάνετε το ίδιο πράγμα εάν το αν η δήλωση είναι αληθής ή ψευδής.

Θα πρότεινα ίσως σκόπευε να κάνει διαφορετικά πράγματα εδώ, ίσως μία από αυτές θα πρέπει να πούμε self.insert (node.lchild, someNumber);

Απαντήθηκε 26/11/2018 στις 16:21
πηγή χρήστη

ψήφοι
0

Μια άλλη λύση Python BST

class Node(object):
    def __init__(self, value):
        self.left_node = None
        self.right_node = None
        self.value = value

    def __str__(self):
        return "[%s, %s, %s]" % (self.left_node, self.value, self.right_node)

    def insertValue(self, new_value):
        """
        1. if current Node doesnt have value then assign to self
        2. new_value lower than current Node's value then go left
        2. new_value greater than current Node's value then go right
        :return:
        """
        if self.value:
            if new_value < self.value:
                # add to left
                if self.left_node is None:  # reached start add value to start
                    self.left_node = Node(new_value)
                else:
                    self.left_node.insertValue(new_value)  # search
            elif new_value > self.value:
                # add to right
                if self.right_node is None:  # reached end add value to end
                    self.right_node = Node(new_value)
                else:
                    self.right_node.insertValue(new_value)  # search
        else:
            self.value = new_value

    def findValue(self, value_to_find):
        """
        1. value_to_find is equal to current Node's value then found
        2. if value_to_find is lower than Node's value then go to left
        3. if value_to_find is greater than Node's value then go to right
        """
        if value_to_find == self.value:
            return "Found"
        elif value_to_find < self.value and self.left_node:
            return self.left_node.findValue(value_to_find)
        elif value_to_find > self.value and self.right_node:
            return self.right_node.findValue(value_to_find)
        return "Not Found"

    def printTree(self):
        """
        Nodes will be in sequence
        1. Print LHS items
        2. Print value of node
        3. Print RHS items
        """
        if self.left_node:
            self.left_node.printTree()
        print(self.value),
        if self.right_node:
            self.right_node.printTree()

    def isEmpty(self):
        return self.left_node == self.right_node == self.value == None


def main():
    root_node = Node(12)
    root_node.insertValue(6)
    root_node.insertValue(3)
    root_node.insertValue(7)

    # should return 3 6 7 12
    root_node.printTree()

    # should return found
    root_node.findValue(7)
    # should return found
    root_node.findValue(3)
    # should return Not found
    root_node.findValue(24)

if __name__ == '__main__':
    main()
Απαντήθηκε 14/04/2019 στις 15:07
πηγή χρήστη

ψήφοι
0
    def BinaryST(list1,key):
    start = 0
    end = len(list1)
    print("Length of List: ",end)

    for i in range(end):
        for j in range(0, end-i-1):
            if(list1[j] > list1[j+1]):
                temp = list1[j]
                list1[j] = list1[j+1]
                list1[j+1] = temp

    print("Order List: ",list1)

    mid = int((start+end)/2)
    print("Mid Index: ",mid)

    if(key == list1[mid]):
        print(key," is on ",mid," Index")

    elif(key > list1[mid]):
        for rindex in range(mid+1,end):
            if(key == list1[rindex]):
                print(key," is on ",rindex," Index")
                break
            elif(rindex == end-1):
                print("Given key: ",key," is not in List")
                break
            else:
                continue

    elif(key < list1[mid]):
        for lindex in range(0,mid):
            if(key == list1[lindex]):
                print(key," is on ",lindex," Index")
                break
            elif(lindex == mid-1):
                print("Given key: ",key," is not in List")
                break
            else:
                continue


size = int(input("Enter Size of List: "))
list1 = []
for e in range(size):
    ele = int(input("Enter Element in List: "))
    list1.append(ele)

key = int(input("\nEnter Key for Search: "))

print("\nUnorder List: ",list1)
BinaryST(list1,key)
Απαντήθηκε 02/01/2020 στις 17:20
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more