⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btreeinterioruos.java

📁 国外的数据结构与算法分析用书
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        If the node is not to be deleted, the second item of the pair specifies
        its new low value or null.  If the node is to be deleted, the second 
        item is always null unless the deleted node is the first node of the 
        parent.  In this latter case, a non-null value is the correct low 
        value for the second child.  A null value indicates the ancestor already has
        the correct value, unless the deletion node is leaf. <br>
        Analysis : O(h*order) + O(h) file reads and writes,
            where h = the height of the tree rooted at this node. 
        @param itemKey The key of the item to delete */
    public PairUos delete(Comparable itemKey, BtreeFileUos treeHeader) 
    {
        int deletionIndex = obtainIndex(itemKey);
        BtreeNodeUos deletionChild = child(deletionIndex);
        PairUos pair = deletionChild.delete(itemKey, treeHeader);

        if (((Boolean)pair.firstItem()).booleanValue())
        {
            /* The deletion child needs to be deleted */
            Comparable newKeyForParent; 
            if (deletionIndex == 1)
                if (deletionChild instanceof BtreeLeafUos)
                    newKeyForParent = getKey(2);
                else
                    /* One or more children of child 1 have been moved to child 2.
                       The low value for this node is the low value of one of these moved
                       children.  The second item of the pair indicates whether the parent
                       key needs to be updated or not. */
                    newKeyForParent = (Comparable)pair.secondItem();
            else
                newKeyForParent = null; 

            shuffleChildrenLeft(deletionIndex+1);
            childCount--;  

            if (childCount == 0) 
            {
                nodeFile.recoverNodeAddress(fileAddress());
                return new PairUos(new Boolean(true), null);
            }
            else if ((childCount >= order + 1) | (parent == null))
            {
                nodeFile.writeNode(this);
                return new PairUos(new Boolean(false), newKeyForParent);
            }
            else 
            {
                BtreeInteriorUos sibling = adjacentSibling();   
                if (sibling.childCount > order + 1) 
                {
                    /* Sibling can spare a child */
                    long newFileAddress;
                    if (fileAddress() == parent.getChildFileAddress(parent.childCount))
                    {
                        /* `this' is the last child of the parent, so sibling on the left */
                        newFileAddress = sibling.getChildFileAddress(sibling.childCount);     
                        sibling.putChildFileAddress(0, sibling.childCount);
                        /* Update my key in parent for use by suffleChildrenRight.
                           It will be overwritten later by the last key of sibling. */
                        if (newKeyForParent != null)
                            parent.putKey(newKeyForParent, parent.childCount);
                        newKeyForParent = sibling.getKey(sibling.childCount);
                        sibling.putKey(null, sibling.childCount);
                        sibling.setChildCount(sibling.childCount - 1);
                        nodeFile.writeNode(sibling);
                        shuffleChildrenRight(1);
                        putChildFileAddress(newFileAddress, 1);           
                        child(1).setParent(this);
                        childCount = childCount + 1;
                        nodeFile.writeNode(this);
                        return new PairUos(new Boolean(false), newKeyForParent);
                    }
                    else
                    {
                        /* The sibling is on the right. */
                        newFileAddress = sibling.getChildFileAddress(1);
                        /* The low key for the child that `this' is taking
                           is the key of the parent for the sibling */
                        int newKeyIndex = parent.indexOfAddress(sibling.fileAddress());
                        Comparable newKey = parent.getKey(newKeyIndex);
                        parent.putKey(sibling.getKey(2), newKeyIndex);
                        nodeFile.writeNode(parent);
                        sibling.shuffleChildrenLeft(2);
                        sibling.setChildCount(sibling.childCount - 1);
                        nodeFile.writeNode(sibling);
                        putChildFileAddress(newFileAddress, childCount + 1);
                        putKey(newKey, childCount + 1);
                        childCount = childCount + 1;
                        child(childCount).setParent(this);
                        nodeFile.writeNode(this);
                        return new PairUos(new Boolean(false), newKeyForParent);
                    }
                }
                else
                {
                    /* Sibling has no children to spare so give it mine */
                    /* Update my key in parent for use by appendChildren and prependChildren */
                    int indexInParent = parent.indexOfAddress(fileAddress());
                    if (newKeyForParent != null & indexInParent != 1)
                    {
                        parent.putKey(newKeyForParent, indexInParent);
                        newKeyForParent = null;
                    }
                    /* When indexInParent == 1, newKeyForParent is passed to the parent
                       where it can be used to update the key in the grandparent. */
                       
                    if (indexInParent == parent.childCount)
                    {
                        /* this node is last child of parent, and sibling is on left */
                        sibling.appendChildren(this);    
                    } 
                    else
                    {
                        /* Sibling is on the right */
                        sibling.prependChildren(this);
                    }

                    childCount = 0;
                    nodeFile.recoverNodeAddress(fileAddress());
                    return new PairUos(new Boolean(true), newKeyForParent);           
                }
            }
        }
        else
        {
            /* Although the child need not be deleted, there might be a new key 
                value for the child */
            if (deletionIndex > 1)
            {
                if (pair.secondItem()!=null)
                {
                    putKey((Comparable)pair.secondItem(), deletionIndex);
                    nodeFile.writeNode(this);
                }
                return new PairUos(new Boolean(false), null);
            }
            else
                return pair;
        }
    }


    /** Returns a string representation of the node. <br>
        Analysis : Time = O(childCount) */
    public String toString()
    {
        String result = "";
        for (int i = 1; i <= childCount; i++)
            result += child(i);
        return result;
    }
    
    /** Returns a string representation of the complete node. <br>
        Analysis : Time = O(order) */
    public String toStringComplete()
    {
        String result = "";
        for (int i = 1; i <= 2*order+1; i++)
        {
            result += "\n          " + getChildFileAddress(i);
            if (i < 2*order+1)
                if (getKey(i+1) != null)
                    result += "\n" + getKey(i+1);
                else
                    result += "\nnull";
        }
        return result;
    }
    
    /** Return a string representation of the node with the proper indentation. <br>
        Analysis: Time = O(h*order), where h = the height of the tree rooted at this node. */   
    public String formatToString(int index, String indentation)
    {
        String result = "\n" +indentation + index+ ":" + "Internal : ";
        String nextindentation = indentation + "        ";
        
        for (int i = 1; i <= 2*order+1; i++)
        {
            result +="  Adr:  "+ getChildFileAddress(i) + "   ";
            if (i < 2*order+1)
                if (getKey(i+1) !=null)
                    result += "Key:  "+ getKey(i+1);
                else
                    result += "Key:  null";
        }
        
        for (int i =1; i <= childCount; i++)
        {
            result += child(i).formatToString(i, nextindentation);
        }
        return result;  
    }
 
    /** Shift the children one position left starting from startIndex,
        without attempting to save a possible low value. <br>
        Analysis : Time = O(childCount - startIndex)
        @param startIndex The index where shuffling will start */
    private void shuffleChildrenLeft(int startIndex)
    {
        /* Should have precondition startIndex >= 2 */
        for (int i = startIndex; i <= childCount; i++)
        {  
            putChildFileAddress(getChildFileAddress(i), i-1);
            if (i > 2) 
                putKey(getKey(i), i-1);
        }
        putChildFileAddress(0, childCount);
        putKey(null, childCount);
    } 

    /** Shift the children one position right starting from startIndex,
        using key in parent if necessary. <br>
        Analysis : Time = O(childCount - startIndex) 
        @param startIndex The index where shuffling will start */
    public void shuffleChildrenRight(int startIndex) 
    {
        /* Should have precondition childCount < 2*order+1 */
        for (int i = childCount; i >= startIndex; i--)
        { 
            putChildFileAddress(getChildFileAddress(i), i+1);

            if (i > 1)
                putKey(getKey(i), i+1); 
            else 
            {
                int indexInParent = parent.indexOfAddress(fileAddress());
                putKey(parent.getKey(indexInParent), 2);
            }
        }
    }

    /** Append the children of node onto the end of the children of this.  This 
        includes copying over key values and saving this node to disk. 
        Note that node is always the right sibling, whose key in parent is used. <br>
        Analysis : Time = O(node.childCount) + 1 file write and read. 
        @param node The node that children will be taken from */
    public void appendChildren(BtreeInteriorUos node)
    {
        int myIndex = childCount + 1;
        for (int nodeIndex = 1; nodeIndex <= node.childCount; nodeIndex++)
        {    
            putChildFileAddress(node.getChildFileAddress(nodeIndex), myIndex);
            child(myIndex).setParent(this);
            if (nodeIndex == 1) 
            {
                int indexInParent = parent.indexOfAddress(node.fileAddress());
                putKey(parent.getKey(indexInParent), myIndex);
            }
            else
                putKey(node.getKey(nodeIndex), myIndex); 
            
            myIndex++; 
        }
        childCount = childCount + node.childCount;
        nodeFile.writeNode(this);
    }
 
    /** Prepend the children of node to the children of this.  This includes 
        copying over the key values.  Node is always the left sibling, whose
        key value in parent is used, if it exists.  Also, a new key value
        is placed in the parent for the current node. <br>
        Analysis : Time = O(childCount) + 1 file read and one write.
        @param node The node that children will be taken from */
    public void prependChildren(BtreeInteriorUos node)
    {
        /* node is to be removed so assign its arrays to this, after saving the current contents. */
        long[] oldChildAddress = childFileAddress;
        Comparable[] oldKeys = keys;
        int oldChildCount = childCount;
      
        childFileAddress = node.childFileAddress;
        keys = node.keys;
        childCount = node.childCount;
        for (int i = 1; i <= childCount; i++)
            child(i).setParent(this);
            
        int indexInNew = childCount + 1;
        for (int indexInOld=1; indexInOld<=oldChildCount; indexInOld++)
        { 
            /* Need to use offset of -1 in oldChildAddess and -2 in oldKeys. */
            putChildFileAddress(oldChildAddress[indexInOld-1], indexInNew);
            if (indexInOld == 1)
            {
                int indexInParent = parent.indexOfAddress(fileAddress());
                putKey(parent.getKey(indexInParent), indexInNew);
                if (indexInParent > 2)
                    parent.putKey(parent.getKey(indexInParent-1), indexInParent);
                /* if (indexParent=2) parent.getKey(2) is handled in invoking method. */
            }
            else
                putKey(oldKeys[indexInOld-2], indexInNew);
                 
            indexInNew++;
        }
        childCount = oldChildCount + childCount;
        nodeFile.writeNode(this);   
    }

    /** Return a child of the parent that is adjacent to this node. <br> 
        Analysis : Time = O(childCount) + 1 file read. */
    public BtreeInteriorUos adjacentSibling()
    {
        if (parent == null) 
            return null;
        else
        {    
            int indexInParent = parent.indexOfAddress(fileAddress());
            if (indexInParent == parent.childCount)
                return (BtreeInteriorUos) parent.child(indexInParent-1);
            else
                return (BtreeInteriorUos) parent.child(indexInParent+1);        
        }
    }

    /** Return the index within the childFileAddress array where the address compAddress 
        exists.  It returns 0 if the address is not in the address array. <br>
        Analysis: Time = O(childCount)
        @param compAddress The address being sought */
    public int indexOfAddress(long compAddress) 
    {
        int result;
        for (result=1; (result <= childCount) && (getChildFileAddress(result) != compAddress); result++);
        return result;
    }
    
    /** The smallest key value of the tree.  If the correct key is not stored 
        for a child in this node or a descendant node throw an exception. <br>
        Analysis : Time = O(n) file reads, n = number of descendant nodes */
    protected Object minOfValidTree()
    {
        Object result = child(1).minOfValidTree();
        for (int i=2; i <= childCount; i++)
            if (!getKey(i).equals(child(i).minOfValidTree()))
                throw new RuntimeException("Error in structure of the Btree");
        return result;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -