Sei sulla pagina 1di 7

# Chapter 27.7 # IMPLEMENTATION OF A B-TREE class queue: def __init__(self): self.front = self.

rear = qnode() class qnode: def __init__(self): self.op = node() self.next = None def qEmpty(q): if(q == None): return 1 else: return 0 def qPush(q, op): # pushes op at q.rear ptr = qnode() ptr.op = op ptr.next = None if(qEmpty(q) == 1): q = queue() q.front = ptr else: q.rear.next = ptr q.rear = ptr return q def qPop(q): # pops op from q->front #print("we are here") ptr = q.front if(qEmpty(q) == 1): return None,None if(qEmpty(q.front) == 1): return None,None q.front = q.front.next print("42") if(qEmpty(q) == 1): q.rear = None op = ptr.op return q, op # /*************************** b.c ****************************/ K = 5 FALSE = 0 TRUE = 1 class node: def __init__(self): self.val = [0 for i in range(K)] # data in the node self.ptr = [None for i in range(K+1)] # pointers to other nodes in the n ode self.nptr = 0 # no of pointers in the node = non-null ptrs self.nval = 0 # no of values in the node

def bNew(): # returns a new initialized node tree = node() tree.nval = tree.nptr = 0 return tree def insertVal(tree, val, ptr): # insert (val, ptr) in node pointed to by tree without any checks i = 0 while(i < tree.nval and tree.val[i] < val): i = i + 1 """ // the val should be inserted at tree->val[i]. // shift-next the next values by one position. """ for j in range(tree.nval-1, i-1, -1): tree.val[j+1] = tree.val[j] tree.ptr[j+2] = tree.ptr[j+1] # insert val now at i tree.val[i] = val tree.nval = tree.nval + 1 tree.ptr[i + 1] = ptr if(ptr != None): tree.nptr = tree.nptr + 1 print("val " + str(val) + " inserted at position "), print(str(i) + " , tree-> nptr= " +str(tree.nptr)), print("nval = " +str(tree.nval)) return tree def getSplitNode(tree): # returns a new node containing vals and pointers from tree ptr = bNew() j = 0 for i in range((K -1)/2+1, K): ptr.ptr[j] = tree.ptr[i] j = j + 1 ptr.nval = K/2 tree.nval = K-K/2-1 print("95") if(tree.nptr > 0): ptr.nptr = K/2+1 tree.nptr =K-K/2 else: tree.nptr = ptr.nptr = 0 #return ptr, tree print("101") return ptr def bMakeChanges(tree, ptr, parent): """ /* * last val of tree contains an extra val which should be * inserted in parent. * if parent == NULL, then tree was root. * tree = parent->ptr[i] if parent is NOT NULL. */ """ # extract the last value from tree print("trss nval 115")

print(tree.nval) val = tree.val[tree.nval] print("in bMake Changes()") if(parent == None): print("122") parent = bNew() parent.ptr[0] = tree parent.nptr = 1 if(parent.nval < K-1): print("127") parent = insertVal(parent, val, ptr) else: print("129") print("parent is full") parent = insertVal(parent, val, ptr) return getSplitNode(parent) def bInsert(tree, val): """ /* * calls insert to insert val in tree. * if the return node is diff from tree, that means a new node has * been created. Thus calls bMakeChanges(). */ """ ptr = insert(tree, val) if(ptr != tree): print("line 138") return bMakeChanges(tree, ptr, None) return tree def insert(tree, val): """ /* * inserts val in tree. * returns tree if there is no change. * if there is creation of a new node then the new node is returned. */ """ if(tree.nptr > 0): print("148") i = 0 while(i < tree.nval and tree.val[i]<val ): i = i+ 1 print("\tval should be inserted in tree->ptr[" +str(i)+"]") ptr = insert(tree.ptr[i], val) if(ptr != tree.ptr[i]): print("155") return bMakeChanges(tree.ptr[i], ptr, tree) return tree else: print("159") if(tree.nval < K-1): tree = insertVal(tree, val, None) return tree else: print("164)") print("\tleaf is full.\n") tree = insertVal(tree, val, None) # now break the leaf node.

return getSplitNode(tree) def getAdjTree(tree, offset, parent, treeindex): # returns parent[treeindex+offset] if exists else NULL. newindex = treeindex + offset if(newindex >= 0 and newindex < parent.nptr): return parent.ptr[newindex] return None def combineNodes(left, right): # left += right. nptrleft = left.nptr for i in range(right.nval): left.val[left.nval] = right.val[i] for i in range(right.nval): left.ptr[nptrleft+i] = right.ptr[i] if(left.nptr > 0): left.nptr += i return left, right def getNextVal(ptr): # return the first value in the first leaf accessible from ptr if(ptr.nptr > 0): return getNextVal(ptr.ptr[0]) return ptr.val[0] def deleteVal(tree, i): """ /* * remove (val, ptr) at position i from tree without any checks. * and return tree->ptr[i+1]. */ """ rightptr = tree.ptr[i + 1] if(i == -1): return 0 for i in range(i+1, tree.nval): tree.val[i - 1] = tree.val[i] tree.ptr[i] = tree.ptr[i + 1] tree.nval = tree.nval - 1 if(tree.nptr > 0): tree.nptr = tree.nptr - 1 return rightptr def bApplyChanges(tree, parent, treeindex): """ /* * apply changes: tree is a non-leaf and tree = parent- >ptr[treeindex]. * also tree->nval < K/2. */ """ offset = -1 if(parent != None and tree.nval >= K/2): return tree elif(parent ==None and tree.nval == 0): return tree.ptr[0] elif(parent == None): return tree # parent is NOT NULL adjtreeleft = adjtree = getAdjTree(tree, offset, parent, treeindex) # predec

essor if(adjtree == None or (adjtree != None and adjtree.nval <= K/2)): offset =1 adjtree = getAdjTree(tree, offset, parent, treeindex) if( adjtree == None or (adjtree != None and adjtree.nval <= K/2)): #print("combine tree, parent median val, adjtree") #print(also check parent for having <K/2 vals.\n") # it is NOT possible that adjtreeleft and right both are NULL. #make adjtree point to the one which is NOT NULL if (adjtree == None): adjtree = adjtreeleft offset = -1 # adjtree points to the sibling: left or right parentvalindex = (2*treeindex+offset)/2 # the parent val is indexed parentval = parent.val[parentvalindex] deleteVal(parent, parentvalindex) # the return val is tree/adjtree. Hence dont worry if(offset == -1): # combine adjtree, parentval and tree. adjtree.val[adjtree.nval] = parentval adjtree.nval = adjtree.nval + 1 adjtree, tree = combineNodes(adjtree, tree) returntree = adjtree else: """ // offset == 1: right sibling. // combine tree, parentval and adjtree.""" tree.val[tree.nval] = parentval tree.nval = tree.nval + 1 adjtree, tree = combineNodes(adjtree, tree) returntree = adjtree return returntree, parent else: adjtreevalindex = adjtree.nval-1 returntree = tree parentvalindex = (2*treeindex+offset)/2 # insert parent val in tree. tree = insertVal(tree, parent.val[parentvalindex], returntree.ptr[0]) # now promote val in adjtree to parent parent.val[parentvalindex] = adjtree.val[adjtreevalindex] returntree.ptr[0] = deleteVal(adjtree, adjtreevalindex) return tree, parent def delete(tree, val, i, parent, treeindex): """ /* * delete val from tree. val == tree->val[i]. * and tree == parent->nptr[treeindex]. */ """ if(tree.nptr == 0): tree = deleteVal(tree, i) else: nextval = getNextVal(tree.ptr[i+1]) tree.val[i] = nextval tree, parent = bDelete(tree.ptr[i+1], nextval, treeindex) return bApplyChanges(tree, parent, treeindex) def bDelete(tree, val, parent, treeindex):

""" /* * delete val from tree if exists. * tree == parent[treeindex]. */ """ i = 0 while(i < tree.nval and tree.val[i]): i = i + 1 if(tree.val[i] == val): print("val = " + str(val) + " found: to be deleted") return delete(tree, val, parent,treeindex) elif(tree.nptr > 0): # printf("val=%d may be in tree->ptr[%d].\n", val, i) tree, parent = bDelete(tree.ptr[i], val, tree, i) return bApplyChanges(tree, parent, treeindex) else: print("val=" + str(val) + " does not exist\n") return tree, parent def bPrintFormatted(tree): ptr = node() q = None q = qPush(q,None) if(qEmpty(q) == 1): print("Push is ok") q = None q = qPush(q, tree) q =qPush(q,None) i = 0 print("-----------------------------------------------") while(qEmpty(q) == 0): print("325") q, ptr = qPop(q) if(ptr != None): print(ptr.nval) for i in range(ptr.nval-1): print(str(ptr.val[i]) + "-"), i = i+1 if(i< ptr.nval): print(ptr.val[i]) for i in range(ptr.nptr): q = qPush(q,ptr.nptr[i]) else: print("\n") if(qEmpty(q) == 0): q = qPush(q, None) q = None print("--------------------------------------------------------") def main(): tree = bNew() tree = bInsert(tree, 1) print("after insert 1") bPrintFormatted(tree) tree = bInsert(tree, 3) tree = bInsert(tree, 6) tree = bInsert(tree, 4) #tree = bInsert(tree, 5) #bPrintFormatted(tree)

main()

Potrebbero piacerti anche