LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: zonzi

谁能帖个java实现二进制树的例子?

[复制链接]
 楼主| 发表于 2004-7-8 04:47:53 | 显示全部楼层
多谢梁博士,过几个星期去试试
发表于 2004-7-10 12:24:22 | 显示全部楼层
好了, 我整个关于2-4 tree, Red-black tree 和 2-4, Red-black tree转换的class写出来了, 但很长, 你们将就点看吧。。。。。。[PHP]/******************************************************************************************
This project is to write a Java class that can take any red-black tree and convert it into
its corresponding (2.4) tree and can take any (2,4) tree convert it into its corresponding
red-black tree.
There are three following main classes:
1. A class called RBTree implementing the Dictionary ADT using a red-black search tree

2. Another class called TwoFourTree implementing the Dictionary ADT using a 2-4 search tree

3. The other class called Convert that can take any red-black tree and convert it into its
   corresponding (2,4) tree and can take any (2,4) tree and convert it into its corresponding
   red-black tree

programmer: Qian-Ru Liang
Date: 6-26-2004
*********************************************************************************************/


class item{
        private Object key, element;

        item(Object k, Object e){
                key = k;
                element = e;
        }

        item(Object k){
                key = k;
        }

        item (){
                key = null;
                element = null;
        }



        public Object element() { return element; }

        public Object key() { return key;}

        public void setelement(Object e){ element = e; }

        public void setkey(Object k) { key = k; }

}

class twofourNode{
        private item itemArray[];
        private twofourNode linkArray[];   // children link array
        private twofourNode parent;
        private int itemlength;           // length for itemArray
        private int linklength;          //  length for linklength
        private IntegerComparator comp;
        private int linkadded, linkremoved;  // the lastest index that link inserted and removed

        // constructor
        twofourNode(){
                itemlength = 0;
                linklength = 1;
                itemArray = new item[4];
                linkArray = new twofourNode[1];
                parent = null;
                linkadded = -1;
                linkremoved = -1;
                comp = new IntegerComparator();
        }

        twofourNode(twofourNode p){
                itemlength = 0;
                linklength = 1;
                itemArray = new item[4];
                linkArray = new twofourNode[1];
                parent = p;
                linkadded = -1;
                linkremoved = -1;
                comp = new IntegerComparator();
        }

        twofourNode(int noItem){
                itemlength = noItem;
                linklength = itemlength + 1;
                itemArray = new item[4];
                linkArray = new twofourNode[linklength];
                parent = null;
                linkadded = -1;
                linkremoved = -1;
                comp = new IntegerComparator();
        }

        twofourNode(int noItem, twofourNode p){
                itemlength = noItem;
                linklength = itemlength + 1;
                itemArray = new item[4];
                linkArray = new twofourNode[linklength];
                parent = p;
                linkadded = -1;
                linkremoved = -1;
        }

        // Query methods
        public int size(){ return itemlength; }
        public boolean overflow(){ return (itemlength == 4); }
        public boolean underflow(){ return (itemlength == 0); }
        public int nolink(){ return linklength; }
        public int getlinkadded() { return linkadded; }
        public int getlinkremoved() { return linkremoved; }

        // Access methods
        public Object[] getkeys(){
                Object keys[] = new Object[itemlength];
                for (int i = 0; i <= itemlength - 1; i++)
                        keys = itemArray.key();
                return keys;
        }

        // searchkey function return an index of the key located in the itemArray
        public int searchkey(Object k){
                int i = 0;
                while (i < itemlength && !comp.isEqualTo(k,itemArray.key()))
                        i++;

                return i;
        }


        public Object getelement(Object k){
                int i = searchkey(k);
                return itemArray.element();
        }

        public Object[] getelements(){
                Object elements[] = new Object[itemlength];
                for (int i = 0; i <= itemlength - 1; i++)
                        elements = itemArray.element();
                return elements;
        }

        public item[] getItems(){
                item temp[] = new item[itemlength];
                for (int i = 0; i < itemlength; i++)
                        temp = itemArray;
                return temp;
        }

        public item getItem(Object k){
                int i = searchkey(k);
                return itemArray;
        }

        // Obtain all child links in this twofourNode
        public twofourNode[] getchildren(){
                twofourNode info[] = new twofourNode[linklength];
                for (int i = 0; i < linklength; i++)
                        info = linkArray;
                return info;
        }


        public twofourNode getparent(){ return parent; }

        // Obtain the right child link relative to k
        public twofourNode getrightchild(Object k){
                int i;
                i = searchkey(k);
                return linkArray[i + 1];
        }

        // Obtain the left child link relative to k
        public twofourNode getleftchild(Object k){
                int i;
                i = searchkey(k);
                return linkArray;
        }

        // Obtain the leftmost child link
        public twofourNode getleftmost(){ return linkArray[0]; }

        // Obtain the rightmost child link
        public twofourNode getrightmost() { return linkArray[linklength - 1]; }

        // Obtain the item with smallest key --> leftmost item
        public item getsmallest() { return itemArray[0]; }

        // Obtain the item with greatest key --> rightmost item
        public item getgreatest() { return itemArray[itemlength - 1]; }

        // Obtain the item with the mid key --> middle item if it is avaliable
        public item getmid() { return itemArray[1]; }


        // supportive methods for update methods

        // find the exact index that the item should be inserted
        public int insertindex(Object k){
                int i;
                for (i = 0; i < itemlength; i++){
                        if (comp.isLessThan(k, itemArray.key()))
                                return i;
                        i++;
                }
                return i;
        }

        // copy the old child links to a new link array with old linklength plus 1 --> for addchild() and removechild functions

        public void copylink(int volume){                                  // for addlinks && removelinks
                twofourNode temp[] = new twofourNode[linklength];
                for (int i = 0; i <= volume - 1; i++)                  // copy the old child links
                        temp = linkArray;
                linkArray = temp;
        }



        // **There is a relationship between index of item inserted(i) or removed and that of child link added(j) or deleted: j = i + 1;
        // update methods
        public void insertItem(item input){
                Object k = input.key();
                int i;

                if(underflow()){
                        itemArray[0] = input;
                        itemlength++;
                        linkadded = 1;
                }
                else if(comp.isGreaterThan(k, itemArray[itemlength - 1].key())){
                        itemArray[itemlength] = input;
                        itemlength++;
                        linkadded = itemlength;
                }

                else{
                        i = insertindex(k);
                        for (int j = itemlength - 1; j >= i; j--)
                                itemArray[j + 1] = itemArray[j];
                        itemArray = input;
                        itemlength++;
                        linkadded = i + 1;
                }

        }

        public item removeItem(item input){
                Object k = input.key();
                int i;
                item temp = input;

                i = searchkey(k);

                for (int j = i; j <= itemlength - 2; j++)
                        itemArray[j] = itemArray[j + 1];
                itemlength--;
                linkremoved = i + 1;
                return temp;
        }

        public void addchild(twofourNode p, int linkadded){
                int volume = linklength;
                linklength++;
                copylink(volume);
                if (linkadded == linklength - 1)
                        linkArray[linkadded] = p;
                else{
                        for (int i = volume - 1; i >= linkadded; i--)
                                linkArray[i + 1] = linkArray;
                        linkArray[linkadded] = p;
                }
        }


        public twofourNode removechild(int linkremoved){
                twofourNode temp = linkArray[linkremoved];
                for (int i = linkremoved; i <= linklength - 2; i++)
                        linkArray = linkArray[i + 1];
                linklength--;
                copylink(linklength);
                return temp;
        }

        public void setparent(twofourNode p){ parent = p; }

        public void setleftchild(twofourNode p, Object k) {
                int i = searchkey(k);
                linkArray = p;
        }

        public void setrightchild(twofourNode p, Object k) {
                int i = searchkey(k);
                linkArray[i + 1] = p;
         }

        public void setrightmost(twofourNode p){ linkArray[itemlength - 1] = p; }

        public void setleftmost(twofourNode p) { linkArray[0] = p; }

        public void printkeys() {
                Object temp[] = getkeys();
                Integer a;
                for (int i = 0; i < temp.length; i++){
                        a = (Integer)temp;
                        System.out.print(a.intValue() +  " ");
                }
        }


}


class twofourTree{
        private twofourNode root;
        int size;
        IntegerComparator C;
        int capacity;

        twofourTree(IntegerComparator c){
                root = new twofourNode();
                size = 0;                         // number of internal nodes
                C = c;
                capacity = 1000;
        }

        twofourTree(){
                root = new twofourNode();
                size = 0;                     // number of internal nodes
                capacity = 1000;
                C = new IntegerComparator();
        }

        // Auxiliary methods

        // findnode() is the way to find the exact node where the item is located at. If reachs external node, then no item found.
        public twofourNode findnode(Object k, twofourNode p){
                if (isExternal(p)) // p.size() == 0--> underflow
                        return p;

                else {
                        int casecontrol = p.size();
                        Object[] v = p.getkeys();
                        if (casecontrol == 1){

                                        if (C.isLessThan(k, v[0])){
                                                p = p.getleftchild(v[0]);
                                                return findnode(k, p);
                                        }
                                        else if (C.isGreaterThan(k, v[0])){
                                                p = p.getrightchild(v[0]);
                                                return findnode(k, p);
                                        }
                                        else
                                                return p;
                        }


                        else if (casecontrol == 2){
                                        if (C.isLessThan(k, v[0])){
                                                p = p.getleftchild(v[0]);
                                                return findnode(k, p);
                                        }
                                        else if(C.isGreaterThan(k, v[0]) && C.isLessThan(k, v[1])){
                                                p = p.getrightchild(v[0]);
                                                return findnode(k, p);
                                        }

                                        else if(C.isGreaterThan(k, v[1])){
                                                p = p.getrightchild(v[1]);
                                                return findnode(k, p);
                                        }
                                        else
                                                return p;
                        }

                        // when casecontrol == 3
                        else{
                                        if (C.isLessThan(k, v[0])){
                                                p = p.getleftchild(v[0]);
                                                return findnode(k, p);
                                        }
                                        else if(C.isGreaterThan(k, v[0]) && C.isLessThan(k, v[1])){
                                                p = p.getrightchild(v[0]);
                                                return findnode(k, p);
                                        }

                                        else if(C.isGreaterThan(k, v[1]) && C.isLessThan(k, v[2])){
                                                p = p.getrightchild(v[1]);
                                                return findnode(k, p);
                                        }

                                        else if(C.isGreaterThan(k, v[2])){
                                                p = p.getrightchild(v[2]);
                                                return findnode(k, p);
                                        }

                                        else
                                                return p;

                        }



                }
        }


        // supportive method for removeitem();
        public void swap(item remove, item replace){
                item temp = remove;
                Object k, e;
                k = replace.key();
                e = replace.element();
                remove.setkey(k);
                remove.setelement(e);

                k = temp.key();
                e = temp.element();
                replace.setkey(k);
                replace.setelement(k);
        }

        // suportive method for removeitem();
        public twofourNode findswapnode(twofourNode p, Object k){
                p = p.getrightchild(k);
                while (!isExternal(p))
                        p = p.getleftmost();
                p = parent(p);
                return p;
        }

        public void checkKey(Object k) throws InvalidKeyException{
                if(!C.isComparable(k))
                        throw new InvalidKeyException("Key " + k + " is not comparable");

        }

        public void checkTree() throws EmptyTreeException{
                if (size() == 0)
                        throw new EmptyTreeException("The tree is an empty tree!");

        }


        public twofourNode getnextsibling(twofourNode p){
                twofourNode mother = parent(p);
                twofourNode[] temp = mother.getchildren();
                int i = 0;

                while (i < temp.length && temp != p)
                        i++;

                if (i == 0)
                        return temp[i + 1];
                else if (i == temp.length - 1)
                        return temp[i - 1];
                else{
                        if (temp[i + 1].size() > 1)
                                return temp[i + 1];
                        else
                                return temp[i - 1];
                }

        }

        public boolean leftsibling(twofourNode p){
                twofourNode next = parent(p);
                twofourNode[] temp = next.getchildren();
                int i = 0;

                while (i < temp.length && temp != p)
                        i++;

                if (i == 0)
                        return false;
                else if (i == temp.length - 1)
                        return true;
                else{
                        if (temp[i + 1].size() > 1)
                                return false;
                        else
                                return true;
                }

        }

        // Decide which item in the parent is going to transfer to underflow child when itemRemove() is executed
        public item ObtainParentMove(twofourNode child){
                int i;
                twofourNode sibling = getnextsibling(child);
                boolean left = leftsibling(child);
                item Pitems[] = parent(child).getItems();
                twofourNode children[] = parent(child).getchildren();
                for (i = 0; i < children.length; i++){
                        if (children == child)
                                break;
                }
                if (left)
                        return Pitems[i - 1];
                else
                        return Pitems;
        }


        // Access methods
        public twofourNode[] children(twofourNode p) throws NullNodeException{
                if (p.size() == 0)
                        throw new NullNodeException("This node is a null node!");
                return p.getchildren();
         }

        public twofourNode parent(twofourNode p) throws RootNodeException{
                if (isRoot(p))
                        throw new RootNodeException("This node is root without any parent!");
                return p.getparent();
         }

        public twofourNode[] siblings(twofourNode p){

                twofourNode v = parent(p);
                twofourNode s[] = new twofourNode[v.nolink()];
                twofourNode temp[] = children(v);
                int i, j;
                i = 0;

                // this loop is to copy all children except p itself
                while (i < v.nolink()){
                        if (temp != p)
                                s = temp;
                        else
                                s = null;

                        i++;
                }

                // this loop is to find the p's index
                while (i < s.length && s != null)
                        i++;

                j = i;
                if (j == s.length - 1)
                        return s;
                else{
                // shift left
                for (i = j; i <= v.nolink() - 2; i++)
                        s = s[i + 1];
                return s;
                }
        }

// methods of the Dictionary ADT

        //Query Methods
        public int size(){ return size; }

        public boolean isEmpty() { return (size == 0); }

        public boolean isRoot(twofourNode v) { return (v == root); }

        public boolean isInternal(twofourNode v){ return (!v.underflow()); }

        public boolean isExternal(twofourNode v){ return (v.underflow()); }

        public twofourNode root(){ return root; }
        // Preorder traverse the tree
        public void elements(twofourNode v, Object[] result, int index){
                if (isExternal(v))
                        return;

                else{
                        item[] temp = v.getItems();
                        int i;
                        twofourNode children[] = v.getchildren();
                        for (i = 0; i < temp.length; i++){
                                result[index] = temp.element();
                                index++;
                        }
                        for (i = 0; i < v.nolink(); i++)
                                elements(children, result, index);
                }

        }

        // Preorder traverse the tree
        public void keys(twofourNode v, Object[] result, int index){
                if (isExternal(v))
                        return;

                else{
                        item[] temp = v.getItems();
                        int i;
                        twofourNode children[] = v.getchildren();
                        for (i = 0; i < temp.length; i++){
                                result[index] = temp.key();
                                index++;
                        }
                        for (i = 0; i < v.nolink(); i++)
                                keys(children, result, index);
                }
        }

        // for Print()

        public twofourNode findEnd(){
                twofourNode end = root;
                while (!isExternal(end))
                        end = end.getrightmost();
                return end;
        }


        // Access methods
        public Object findElement(Object k) throws InvalidKeyException{
                checkKey(k);

                twofourNode p = root;
                p = findnode(k, p);
                if (!isExternal(p))
                        return p.getelement(k);
                else{
                        System.out.print("No this item found!\n");
                        return null;
                }
        }


        public Object[] findAllElements(Object k) throws EmptyTreeException{
                checkTree();

                twofourNode p = root;
                Object[] result = new Object[capacity];
                int i = 0;
                while (!isExternal(findnode(k, p))){
                        result = p.getelement(k);
                        p = p.getleftchild(k);
                        i++;
                }
                return result;
        }


        // Update methods
        public void expandExternal(twofourNode p, Object k){
                twofourNode temp = new twofourNode(p);
                p.addchild(temp, p.nolink());           // if p is not overflow, after insertion of k, setrightchild to new external
        }


        public void insertitem(item input) throws InvalidKeyException{
                Object k = input.key();
                twofourNode p = root;
                checkKey(k);


                if (isRoot(p) && isExternal(p)){
                        p.insertItem(input);
                        expandExternal(p, k);
                }
                else{
                        p = findnode(k, p);
                        if (isExternal(p)){
                                p = parent(p);
                                p.insertItem(input);
                                expandExternal(p, k);

                                if (p.overflow()){
                                split(p);
                                }


                        }
                        else{
                                while (!isExternal(findnode(k, p)))
                                        p = p.getleftchild(k);

                                p = parent(p);
                                p.insertItem(input);
                                expandExternal(p, k);

                                if (p.overflow()){
                                        split(p);
                                }
                        }
                }

        }

        public item removeitem(Object k) throws InvalidKeyException{
                checkKey(k);
                twofourNode p = root;
                twofourNode w;                     // sibling
                item item1, item2;
                int i;
                boolean left;


                p = findnode(k, p);
                item1 = p.getItem(k);
                if (isExternal(p.getleftmost())){
                        p.removeItem(item1);
                        i = p.getlinkremoved();
                        if (!p.underflow()){ p.removechild(i); }

                        else{
                                w = getnextsibling(p);                 // get left or right sibling of p
                                left = leftsibling(p);                 // check this sibling is on left side of p or not
                                if ( w.size() > 1 )
                                        transfer(p, w, left);          // do transfer if the sibling w has more than two children

                                else
                                        fuse(p, w);                    // do fuse if the sibling w has only two children
                        }
                        return item1;
                }

                else{
                        w = findswapnode(p, k);
                        item2 = w.getsmallest();
                        swap(item1, item2);

                        item1 = p.removeItem(item2);
                        i = p.getlinkremoved();
                        if (!p.underflow()) { p.removechild(i); }

                        else{
                                w = getnextsibling(p);
                                left = leftsibling(p);
                                if (w.size() > 1)
                                        transfer(p, w, left);

                                else
                                        fuse(p, w);
                        }
                        return item1;
                }

        }


        public void split(twofourNode old){
                if (!old.overflow()) { return; }

                else{
                        int i;
                        Object k;
                        twofourNode temp;
                        twofourNode parent = parent(old);

                        // initialize two new nodes in which both their parents are parent of the old node
                        twofourNode left = new twofourNode(2, parent);
                        twofourNode right = new twofourNode(1,parent);
                        item[] tempold = old.getItems();
                        twofourNode[] linkold = old.getchildren();


                        // copy items to new split two nodes
                        for (i = 0; i < 2; i++)
                                left.insertItem(tempold);
                        right.insertItem(tempold[3]);



                        // copy children links of two nodes
                        for (i = 1; i < 3; i++){
                                left.addchild(linkold, i);
                                linkold.setparent(left);
                        }


                        left.setleftmost(linkold[0]);
                        linkold[0].setparent(left);

                        right.setleftmost(linkold[3]);
                        linkold[3].setparent(left);
                        right.setrightmost(linkold[4]);
                        linkold[4].setparent(left);

                        if (isRoot(old)){
                                parent = new twofourNode();
                                root = parent;
                                k = tempold[2].key();
                                // insert third item of old one into parent node
                                parent.insertItem(tempold[2]);
                                i = parent.getlinkadded();
                                // set children links to split nodes
                                parent.addchild(right,i);
                                parent.setleftchild(left, k);
                                size++;
                                return;
                        }

                        else {
                                k = tempold[2].key();
                                parent.insertItem(tempold[2]);
                                i = parent.getlinkadded();
                                parent.addchild(right, i);
                                parent.setleftchild(left, k);
                                size++;
                                split(parent(old));
                        }
                }

        }



        public void fuse(twofourNode old, twofourNode sibling){
                if (isRoot(old)){
                        root = old.getleftmost();
                        return;
                }

                else {
                        int i, j;
                        boolean left;
                        item Pitem;
                        Pitem = ObtainParentMove(old);
                        sibling.insertItem(Pitem);
                        i = sibling.getlinkadded();

                        // copy underflow node's child to its sibling and set the child to new parent: the sibling
                        sibling.addchild(old.getleftmost(), i);
                        old.getleftmost().setparent(sibling);
                        size--;

                        // remove the item from parent;
                        old = parent(old);
                        old.removeItem(Pitem);
                        j = old.getlinkremoved();

                        if (!old.underflow()){
                                old.removechild(j);
                                return;
                        }

                        else{
                                left = leftsibling(old);
                                sibling = getnextsibling(old);
                                if (sibling.size() > 1){
                                        transfer(old, sibling, left);
                                        return;
                                }

                                else
                                        fuse(old, sibling);
                        }
                }
        }


        public void transfer(twofourNode old, twofourNode sibling, boolean leftsibling){
                twofourNode parent = parent(sibling);
                twofourNode copychild;
                int i;
                item Pitem = ObtainParentMove(old);
                item Sitem;
                old.insertItem(Pitem);

                if (leftsibling){
                        Sitem = sibling.removeItem(sibling.getgreatest());
                        copychild = sibling.removechild(sibling.nolink() - 1);
                        copychild.setparent(old);
                        old.addchild(copychild,0);
                }
                else{
                        Sitem = sibling.removeItem(sibling.getsmallest());
                        copychild = sibling.removechild(0);
                        copychild.setparent(old);
                        old.addchild(copychild, old.nolink());
                }

                parent.insertItem(Sitem);
        }

}

// Exception Handler
class InvalidKeyException extends RuntimeException{
        public InvalidKeyException(String err){
                super(err);
        }
}

class NullNodeException extends RuntimeException{
        public NullNodeException(String err){
                super(err);
        }
}

class RootNodeException extends RuntimeException{
        public RootNodeException(String err){
                super(err);
        }
}

class EmptyTreeException extends RuntimeException{
        public EmptyTreeException(String err){
                super(err);
        }
}


class InvalidElementException extends RuntimeException{
        public InvalidElementException(String err){
                super(err);
        }
}


class IntegerComparator{
        private int int1, int2;

        IntegerComparator(){
                int1 = 0;
                int2 = 0;
        }

        private void getinteger(Object a, Object b){
                if (a == null || b == null)
                        throw new InvalidElementException("Null Argument!");
                int1 = ((Integer) a).intValue();
                int2 = ((Integer) b).intValue();
        }

        public boolean isLessThan(Object a, Object b){
                getinteger(a, b);
                if (int1 < int2)
                        return true;
                else
                        return false;
        }

        public boolean isLessThanOrEqualTo(Object a, Object b){
                getinteger(a, b);
                if (int1 <= int2)
                        return true;
                else
                        return false;

        }

        public boolean isEqualTo(Object a, Object b){
                getinteger(a, b);
                if (int1 == int2)
                        return true;
                else
                        return false;
        }

        public boolean isGreaterThan(Object a, Object b){
                getinteger(a, b);
                if(int1 > int2)
                        return true;

                else
                        return false;

        }

        public boolean isGreaterThanOrEqualTo(Object a, Object b){
                getinteger(a, b);
                if(int1 >= int2)
                        return true;
                else
                        return false;

        }

        public boolean isComparable(Object a){
                if (a==null)
                        return false;

                else{
                        try{ Integer b = (Integer) a; }
                        catch (ClassCastException e) { return false;}
                        return true;
                }
        }

}

class RBitem extends item {
        private boolean red;
        public RBitem(Object k, Object elem, boolean color){
                super(k, elem);
                red = color;
        }

        public RBitem(){
                super();
                red = false;
        }

        public boolean isRed() { return red; }
        public void makeRed() { red = true; }
        public void makeBlack() { red = false; }
        public void setColor(boolean color) { red = color; }

}

class RBnode extends RBitem{
        private RBnode parent, left, right'
        RBnode(){ }
        RBnode (Object e, Object k, RBnode u, RBnode v, RBnode w){
                setelement(e);
                setkey(k);
                parent = u;
                left = v;
                right = w;
        }
        public RBnode getleft() { return left; }
        public RBnode getright() { return right; }
        public RBnode getparent() { return parent; }
        public void setleft(RBnode v) { left = v;  }
        public void setright(RBnode v) { right = v; }
        public void setparent(RBnode v) { parent = v; }
        public RBitem getitem(){ return Item; }
}
class RBTree{
        static boolean Red = true;
        static boolean Black = false;
        private root;
        private int size;
        private IntegerComparator C;
        private int capacity;

        RBTree(IntegerComparator c){
                root = new RBnode(null, null, null, null, null);
                size = 0;                         // number of internal nodes
                C = c;
                capacity = 1000;
        }

        RBTree(){
                root = new RBnode(null, null, null, null, null);
                size = 0;                     // number of internal nodes
                capacity = 1000;
                C = new IntegerComparator();
        }

        // Query methods
        public int size() { return size; }
        public boolean isExternal(RBnode p) {
                return (p.getleft() == null && p.getright() == null);
        }

        public boolean isInternal(RBnode p) {
                return (p.getleft() != null && p.getright() != null);
        }

        public boolean isEmpty() { return (size == 0); }

        public RBnode root() { return root; }

        public isRoot(RBnode p) { return (p == root); }

        public RBnode parent(RBnode p) { return p.getparent(); }

        public RBnode leftchild(RBnode p) { return p.getleft(); }

        public RBnode rightchild(RBnode p) { return p.getright(); }

        public RBnode sibling(RBnode v){
                RBnode p = parent(v);
                RBnode lc = leftchild(p);
                if (v == lc)
                        return rightchild(p);
                else
                        return lc;
        }

        public RBnode[] children(RBnode p){
                RBnode children[] = new RBnode[2];
                children[0] = p.getleft();
                children[1] = p.getright();
                return children;
        }


        public Object replaceElement(RBnode v, item newItem){
                item temp = v.element();
                v.setelement(newItem.element(e))
                v.setkey(newItem.key(k));
                return temp;
        }

        public void swapElements(RBnode v, RBnode w){
                Object temp = w.element();
                w.setelement(v.element());
                v.setelement(temp);
        }

        public void expandExternal(RBnode v){
                if(isExternal(v)){
                        v.setleft(new RBnode(null, null, v, null, null));
                        v.setright(new RBnode(null, null, v, null, null));
                }
        }

        public void removeAboveExternal(RBnode v){
                if(isExternal(v)){
                        RBnode p = parent(v);
                        RBnode s = sibling(v);
                        if (isRoot(p)){
                                s.setparent(null);
                                root = s;
                        }
                        else{
                                RBnode g = parent(p);
                                if(p == leftchild(g))
                                        g.setleft(s);
                                else
                                        g.setright(s);
                                s.setparent(g);
                        }

                        size--;
                }
        }





        // Auxiliary methods
        protected void checkKey(Object key) throws InvalidKeyException{
                if(!C.isComparable(k))
                        throw new InvalidKeyException("Key " + k + " is not comparable");

        }

        protected RBitem findPosition(Object key, RBnode pos){
                if (isExternal(pos))
                        return pos;

                else{
                        Object curKey = pos.key();
                        if(C.isLessThan(key, curKey))
                                return findPosition(key, leftchild(pos));
                        else if(C.isGreaterThan(key, curKey))
                                return findPosition(key, rightchild(pos));
                        else
                                return pos;

                }


        }

        public boolean isPosRed(RBnode v){ return v.isRed(); }

        public void setRed(RBnode v) { v.makeRed(); }

        public void setBlack(RBnode v) { v.makeBlack(); }

        public void setColor(RBnode v, boolean newcolor) { v.setcolor(newcolor); }

        public boolean wasParentRed(RBnode v) { return parent(v).isRed(); }

        public boolean hasRedChild(RBnode v) {
                if (rightchild(v).isRed() || leftchild(v).isRed())
                        return true;

                else
                        return false;

        }

        public int height(RBnode v){
                int count;
                if (isExternal(v))
                        return 0;

                else{
                        h = 0;
                        RBnode[] temp = children(v);
                        int i;
                        while (i < temp.length)
                                h = Math.max(h, height(temp));
                        return h + 1;
                }
        }

        public RBnode tallerchild(RBnode v){
                if (height(leftchild(v)) >= height(rightchild(v)))
                        return leftchild(v);

                else
                        return rightchild(v);
        }

        public RBnode redchild(RBnode v){
                if (rightchild(v).isRed())
                        return rightchild(v);

                else if (leftchild(v).isRed())
                        return leftchild(v);

                else
                        return null;
        }

        public void insertItem(Object key, Object element) throws InvalidKeyException{
                checkKey(key);
                RBnode insPos = root();

                do {
                        insPos = findPosition(key, insPos);
                        if(isExternal(insPos))
                                break;
                        else
                                insPos = rightchild(insPos);
                } while(true);

                expandExternal(insPos);
                item newItem = new item(key, element);
                replaceElement(insPos, newItem);

                RBnode posZ = insPos;
                replaceElement(posZ, new RBitem(key, element, Red));
                if (isRoot(posZ))
                        posZ.makeBlack();
                else
                        remedyDoubleRed(posZ);

        }

        public Object removeElement(Object key) throws InvalidKeyException{
                Object toReturn;
                checkKey(key);
                RBnode remPos = findPosition(key, root());
                if(isExternal(remPos){ return NO_SUCH_KEY; }

                else{
                        toReturn = remPos.element();
                        if(isExternal(leftchild(remPos)))
                                remPos = leftchild(remPos);
                        else if (isExternal(rightchild(remPos)))
                                remPos = rightchild(remPos);
                        else{
                                RBnode swapPos = remPos;
                                remPos = rightchild(swapPos);
                                do
                                        remPos = leftchild(remPos);
                                while (isInternal(remPos));
                                swapElements(swapPos, parent(remPos));
                        }
                        removeAboveExternal(remPos);

                        RBnode posR = remPos;
                        if (toReturn != NO_SUCH_KEY){
                                if (wasParentRed(posR) || isRoot(posR) || isPosRed(posR))
                                        setBlacke(posR);
                                else
                                        remedyDouble(Black(posR);

                        }
                        return toReturn;
        }


        protected void remedyDoubleRed(RBnode posZ) {
                RBnode posV = parent(posZ);
                if (isRoot(posV))
                        return
                if(!isPosRed(sibling(posV))){
                        posV = restructure(posZ);
                        setBlack(posV);
                        setRed(leftchild(posV));
                        setRed(rightchild(posV));
                }

                else{
                        setBlack(posV);
                        setBlack(sibling(posV));
                        RBnode posU = parent(posV);
                        if (isRoot(posU))
                                return;
                        setRed(posU);
                        remedyDoubleRed(posU);
                }

        }

        protected void remedyDoubleBlack(Position posR) {
                RBnode posX, posY, posZ;
                boolean oldColor;

                posX = parent(posR);
                posY = sibling(posR);
                if(!isPosRed(posY)){
                        posZ = redChild(posY);
                        if(hasRedChild(posY)){
                                oldColor = isPosRed(posX);
                                posZ = restructure(posZ);
                                setColor(posZ, oldColor);
                                setBlack(posR);
                                setBlack(leftchild(posZ));
                                setBlack(rightchild(posZ));
                                return;
                        }

                        setBlack(posR);
                        setRed(posY);
                        if (!isPosRed(posX)){
                                if (!isRoot(posX))
                                        remedyDoubleBlack(posX);
                        return;
                        }
                        setBlack(posX);
                        return;
                }

                if (posY == rightchild(posX))
                        posZ = rightchild(posY);
                else
                        posZ = leftchild(posY);
                restructure(posZ);
                setBlack(posY);
                setRed(posX);
                remedyDoubleBlack(posR);
        }

        public restructure (RBnode v){
                RBnode a, b, c, x, y, z;

                x = v;
                y = tallerchild(x);
                z = tallerchild(y);

                if (y == leftchild(x) && z == leftchild(y)){
                        a = z;
                        b = y;
                        c = x;
                        swapElements(b, x);
                        b.setleft(a);
                        b.setright(c);
                        c.setleft(b.getright());
                        b.getright().setparent(c);
                        return;
                }

                else if (y == rightchild(x) && z == rightchild(y)){
                        a = x;
                        b = y;
                        c = z;
                        swapElement(b, x);
                        b.setleft(a);
                        b.setright(c);
                        a.setright(b.getleft());
                        b.getleft().setparent(a);
                        return;
                }

                else if (y == rightchild(x) && z = leftchild(y)){
                        a = x;
                        c = y;
                        b = z;
                        swapElement(b, x);
                        b.setleft(a);
                        b.setright(c);
                        a.setright(b.getleft());
                        b.getleft().setparent(a);
                        c.setleft(b.getright());
                        b.getright().setparent(c);
                        return;
                }

                else if (y == leftchild(x) && z = rightchild(y)){
                        a = y;
                        b = z;
                        c = x;
                        swapElement(b, x);
                        b.setleft(a);
                        b.setright(c);
                        a.setright(b.getleft());
                        b.getleft().setparent(a);
                        c.setleft(b.getright());
                        b.getright().setparent(c);
                        return;
                }

                else
                        return;

        }

}




class convert{
        twofourTree mytwofour;
        RBTree myRBtree;

        convert(){
                mytwofour = new twofourTree(1000);
                myRBtree = new RBTree(1000);
        }



        public toTwoFour(RBtree tree, RBnode p1, twofourNode p2){
                if (p1.isRed()){
                        twofourNode parent = p2.getparent();
                        parent.insertItem(p1);
                        int i = parent.getaddchild();
                        twofourNode ltemp = new twofourNode(1, parent);
                        twofourNode rtemp = new twofourNode(1, parent);
                        ltemp.insertItem(leftchild(p1));
                        rtemp.insertItem(rightchild(p1));
                        parent.addchild(ltemp, i - 1);
                        parent addchild(rtemp, i);
                }

                else{
                        p2 = new twofourNode();
                        p2.insertItem(p1);

                }
                toTwoFour(tree, p1.leftchild(), p2.getleftmost());
                toTwoFour(tree, p1.rightchild(), p2.getrightmost());
        }


}        [/PHP]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表