java简单实现二叉搜索树

**

1.二叉排序树的百度百科定义:

**
(1)二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树:
①二叉排序树或者是一棵空树,或者是具有下列性质的二叉树:
1)若左子树不空,则左子树上所有节点的值均小于它的根节点的值。
2)若右子树不空,则右子树上所有节点的值均大于它的根节点的值
3)左、右子树也分别为二叉排序树
4)没有键值相等的节点。
**

2.先补充说明以下对数器:

**
(1) 我们再写完一个程序后,为验证其正确性,往往选择一些测试用例去测试,如写了一个冒泡排序,我们需要验证其正确性,就可以拿我们写的冒泡排序和官方的sort对一组相同元素的数组进行排序,之后对排序后的两个数组进行逐一比较,若有不同的顺序,则打印这个数组,这样子,我们写出来的程序就得到了正确性的验证,如以下就是一个排序的对数器:

          InsertSort insertSort = new InsertSort(20);
        
                for (int i = 0; i < 1000; i++) {
                    insertSort.randomInit();
    
    //copy一份新的数组,和insertSort.arrays一致
                int[] sortArray = Util.copyArray(insertSort.arrays);
                int[] mySortArray = insertSort.sort();
    
                Arrays.sort(sortArray);
    //检查两个数组的元素顺序是否一致
                Util.check(mySortArray,sortArray);
            }

	//Check函数:
		public static void check(int[] array1,int[] array2){
        boolean flag = true;
        for (int i = 0; i < array1.length; i++) {
            if(array1[i]!=array2[i]){
                System.out.println(Arrays.toString(array1));
                System.out.println(Arrays.toString(array2));
                flag = false;
                break;
            }
        }
        if(flag){
            System.out.println("true");
        }else {
            System.out.println("false");
        }
}

今天我们写的bst,也可以使用treeMap进行对照,对数…
**

3.今天就来写一棵 BST。

**
(1)首先,树的组成是节点,故先创建一个节点类:
①思考节点类有什么属性:
1)因为是二叉树,所以有左右节点:left、right,可以再来一个父节点parent。不过此版本不带父节点,读者可以自行改进。
2)有一个value存放节点的内容
3)同时可以有一个key,作为树的权重的参考,
4)为了规范一点,我们实现Map.Entry接口
5)给上属性的get、set的方法,构造函数。
6)一个完整的节点类就出来了:
public class Entry<K,V> implements Map.Entry<K,V> {

private Entry<K,V> left;
private Entry<K,V> right;
private K key;
private V value;


public Entry(V value) {
    this.value = value;
}

public Entry(K key, V value) {
    this.key = key;
    this.value = value;
}

public Entry(Entry<K, V> left, Entry<K, V> right, K key, V value) {
    this.left = left;
    this.right = right;
    this.key = key;
    this.value = value;
}

@Override
public K getKey() {
    return key;
}

@Override
public V getValue() {
    return value;
}

@Override
public V setValue(V value) {
    return value;
}

@Override
public String toString() {
    return "Entry{" +
            " key=" + key +
            ", value=" + value +
            ", }";
}

public Entry<K, V> getLeft() {
    return left;
}

public void setLeft(Entry<K, V> left) {
    this.left = left;
}

public Entry<K, V> getRight() {
    return right;
}

public void setRight(Entry<K, V> right) {
    this.right = right;
}

public void setKey(K key) {
    this.key = key;
}

}

(2)接下来就是主类BSTree:
①思考属性:
1)首先:节点类型 root,
2)Int 类型的 size,
3)貌似没了,不过可以 再来一个 节点 key 类型的比较器,comparetor;
②实现:
1)初始化
Root = null;
Size = 0;
Comparetor = null;
构造函数可分为 无参构造,也可以传一个 比较器进来。
2)方法:
a.比较节点key的权重:入参:返回值 int 大于0表示 key1>key2
a)当 比较器Comparetor 不为空时,则用比较器比较key的权重,当comparator为空时,则必须要key的类实现comparable接口,直接调用compareto方法。若没实现,则抛出异常…
b.返回树的节点数:
c.插入节点:

a)当 root 节点为 null时,则将此key+value新建节点赋值给root。
b)当节点不为null时,比较插入key与节点key的权重大小,若大于,则插入到节点的左侧子树,若左侧子树为空,则将此key+value新建节点赋值给左测子树。
c)若小于,与大于同理。
d)迭代进行插入,同时不要忘记 size++;
d.遍历树:
a)BST的中序序遍历是升序的排列,此例我们就使用中序遍历:
b)总所周知,set中的元素是无顺序的,为什么TreeSet的输出却是有序的呢,是因为在foreach时,使用的时迭代器,这里,我们也使用迭代器去实现我们自己的BST的迭代。
c)实现迭代有两步:
i.能获取iterator的类实现iterable接口,重写iterator方法,返回一个itrator的实例。
ii.新建一个类实现iterator接口,重写hasNext和next方法,hasNext表示是否有下一个元素,next表示取下一个元素。
d)由于此处是中序遍历且无父节点,所以必须借助一个栈来实现:
i.先将所有左侧节点入栈

public void addToStack(Entry<K, V> entry){
    Entry<K,V> temp = entry;
    while (temp!=null){
        stack.push(temp);
        temp = temp.getLeft();
    }
}

ii.在取出时:将此节点的右节点压入栈
i)Addtostack(entry.right);
iii.故:迭代器的属性:树的根节点,一个帮助回溯的辅助栈(若节点右parent的域则不需要)。HasNext的条件为:栈不为空。
iv.Next则为栈顶元素。这样,我们的树就有一个迭代器了。
v.以下为迭代器代码:

public class MyTreeIterator<K,V> implements Iterator<Entry<K,V>> {
    //private ArrayList<Entry<K,V>> arrayList;
    private Stack<Entry<K,V>> stack;
    private Entry<K,V> root;

    public MyTreeIterator(Entry<K, V> root) {
        this.root = root;
        Entry<K,V> temp = root;
        stack = new Stack<>();
        addToStack(temp);
    }
    public void addToStack(Entry<K, V> entry){
        Entry<K,V> temp = entry;
        while (temp!=null){
            stack.push(temp);
            temp = temp.getLeft();
        }
    }

    @Override
    public boolean hasNext() {
        return stack.size()>0;
    }

    @Override
    public Entry<K,V> next() {
        if(stack.size() == 0){
            throw new NoSuchElementException("迭代器中无参数了!!!");
        }
        Entry<K,V> entry = stack.pop();
        if(entry.getRight() != null){
            addToStack(entry.getRight());
        }
        return entry;
    }


    @Override
    public void remove() {

    }
}

③接下来就是BST本身的实现了,根据前面给出的代码:
1)比较key的权重,写一个compare方法,实现如下:

/**
 * compare two key how bigger if key1 more than key2 return num > 0,= 0 is someone.< 0 is letter key2.
 * if comparator is null,use comparable to equally
 * @param key1
 * @param key2
 * @return  >0 or 0 or <0
 */
private final int compare(K key1, K key2){
    if(comparator!=null){
        return comparator.compare(key1,key2);
    }else {
        if(key1 instanceof Comparable){
            Comparable<K> k = (Comparable<K>)key1;
            return k.compareTo(key2);
        }
        throw new ClassCastException(" this class do not implement Comparable interface ");
    }
}

2)返回树的节点数:
Return size即可
3)插入节点:
a.入参:key,value。
b.判断根节点是否为空,为空直接令其等于新节点。
c.每到一个节点,比较key的权重,比节点大,且节点右子树为空,则直接插入,否则节点迭代成左节点。权重比节点权重下,道理同上。若权重一致,则看业务需求,看是替换value还是保留原来的value,这里我偷懒,选择的是保留原value。
d.同时不忘添加时要size++;
e.代码如下:

/**
 * put one key and value to this tree,in this tree create a entry to contains this key and value
 * if this tree has some key equally whit this key , this value will no replace old value , will put fail
 * @param key
 * @param value
 */
public void put(K key,V value){
    if(root == null){
        root = new Entry<>(key,value);
        size++;
    }else {
        Entry<K,V> temp = root;
        while (temp != null){
            int sign = compare(key,temp.getKey());
            if( sign == 0 ){
                break;
            }else if( sign > 0){
                if(temp.getRight() != null){
                    temp = temp.getRight();
                }else {
                    temp.setRight(new Entry<>(key,value));
                    size++;
                    break;
                }
            }else{
                if(temp.getLeft() != null){
                    temp = temp.getLeft();
                }else {
                    temp.setLeft(new Entry<>(key,value));
                    size++;
                    break;
                }
            }

        }
    }
}

4)遍历树由于已经写好迭代器,故很简单:

@Override
public Iterator<Entry<K,V>> iterator() {
    return new MyTreeIterator<>(root);
}

④这样,一颗具有插入,中序遍历的树就形成了,为了更加漂亮,我们再进行一系列的补充:
1)添加获取指定节点的方法getEntryUsingComparator:入参:key,返回值 entry。
a.逻辑基本与插入一致,当key等于null时,我们直接返回null,或者查找失败(查找到叶子节点都没有找到)返回null,找到的依据时key的权重相等,即compare方法的返回值为0,我们就返回 entry节点类对象。
b.因为有时候我们需要key找到指定节点去操作节点,故独立出来一个根据key找节点的方法。
2)添加get函数:入参:key,返回值 value。
a.由于有了获取指定节点的函数,故我们只要调用就行:

Entry<K,V> entry = getEntryUsingComparator(key);
if(entry != null){
    return entry.getValue();
}
return null;

3)添加contains函数:入参:key,返回值 boolean。
a.containsKey:因为key可以进行比较,故查找起来十分简单,这里我们为了可维护性和简洁性,可以直接借助get函数:return get(key)!=null;
b.containsObject:因为object是无顺序的,所以我们查找它时是无任何优化的,故时间复杂度为o(n),并且时遍历整颗树去查找的,这里由于我们之前写了一个迭代器,固使用迭代器进行逐一比较.
c.代码实现:

public boolean containsValue(V value){
    Iterator<Entry<K,V>> it = new MyTreeIterator<>(root);
    while (it.hasNext()){
        if(valEquals(it.next().getValue(),value)){
            return true;
        }
    }
    return false;
}

4)增加获取指定节点后的最小节点:入参 节点entry
a.getFirstEntry(entry p)
b.由于时有序的,故只要找到最左节点即是最小节点:
Entry<K,V> temp = entry;

if (temp != null){
    while (temp.getLeft() != null){
        temp = temp.getLeft();
    }
}
return temp;

5)增加获取最大节点:
a.同获取最小节点一致
6)删除节点函数deleteEntry:入参:entry初始节点,要删除的key。
a.删除节点首先找到指定节点。找到的依据即是:比较函数compare返回值为0
b.删除节点有四种情况:
a)情况1:要删除的节点为叶子节点,直接删除即可
b)情况2:要删除的节点仅有一个左子树,让左子树代替此节点即可
c)情况3:要删除的节点仅有一个右子树,让右子树代替此节点即可
d)情况4:要删除的节点既有左子树也有右子树,此时,需要在左子树找到一个最大节点代替此节点,或者,在右子树找到一个最小节点代替此节点。再进行删除此最小/最大节点,将转变为情况1.
c.这里讲讲情况4:
a)首先,假设寻找到节点p,就是要删除的节点,找到p的左侧的最大权重节点:leftMax = getFirstEntry§;再令p节点的k、v、都等于leftMax节点的k、v。再递归调用本方法删除deleteEntry(p.left).
d.注意size–;
e.未找到删除节点:
a)根据key权重的比较,进行递归调用,如:p.right = deleteEntry(p.right).
private final Entry<K,V> deleteEntry(Entry<K,V> p,K key){
//two child

    if( p == null){
        return null;
    }
    int compareResult = compare(p.getKey(),key);

    //如果 结果为0, 表示找到 要删除节点
    if(compareResult == 0){
        //case 1 :
        if( p.getRight() == null && p.getLeft() == null){
            size--;
            p = null;
        }else if( p.getLeft() != null && p.getRight() == null ){
            size--;
            p = p.getLeft();
        }else if( p.getLeft() == null && p.getRight() != null ){
            size--;
            p = p.getRight();
        }else {
            if( size%2 == 0 ) {
                //left max
                Entry<K, V> leftMax = getLastEntry(p.getLeft());
                //将p转为 leftMax
                p.setKey(leftMax.getKey());
                p.setValue(leftMax.getValue());
                //
                Entry<K, V> newLeft = deleteEntry(p.getLeft(),p.getKey());
                
                p.setLeft(newLeft);
            }else {
                //right min
                Entry<K, V> rightMin = getFirstEntry(p.getRight());
                //将p转为 rightMin
                p.setKey(rightMin.getKey());
                p.setValue(rightMin.getValue());
                Entry<K, V> newRight = deleteEntry(p.getRight(),p.getKey());
                p.setRight(newRight);
            }
        }
    }else if(compareResult < 0){
        //未找到节点,递归调用删除p的右子树
        //将返回值作为新右子树
        Entry<K, V> newRight = deleteEntry(p.getRight(),key);
        p.setRight(newRight);
    }else {
        //未找到节点,递归调用删除p的左子树
        //将返回值作为新左子树
        Entry<K, V> newLeft = deleteEntry(p.getLeft(),key);
        p.setLeft(newLeft);
    }
    //返回新树
    return p;

}
好的,以上就是删除节点的操作了,注意,返回值是新的entry节点。
7)Remove:返回值为:V
a.因为删除的操作时不会有被删除元素的返回的,所以我们先获取,再进行删除
b.获取,直接使用get函数
c.删除,直接调用deleteEntry方法:root = deleteEntry(root,key);这里因为可能会删除根节点,故需要让root等于新的根节点。
(3)这里我们可以看一看官方的treeMap如何实现的:
①寻找后继节点:

 static <K,V> TreeMap.Entry<K,V> successor(TreeMap.Entry<K,V> t) {
             //if t is null ,return null
        if (t == null)
            return null;
             //left --> root --> right print
            //so if this entry has right child,the next entry is right tree leftes child.
        else if (t.right != null) {
            TreeMap.Entry<K,V> p = t.right;
            while (p.left != null)
                p = p.left;
            return p;
        } else {
            //if this entry has no child, to father,and if this node is father right child,should find up level,
            //until root ... if allways not found , this entry has no next.

            TreeMap.Entry<K,V> p = t.parent;
            TreeMap.Entry<K,V> ch = t;
            while (p != null && ch == p.right) {
                ch = p;
                p = p.parent;
            }
            return p;
        }
    }

②删除节点(此处因为treeMap entry 带有父节点,故可以使用递归),可以看到此处也是分为四种情况:

private void deleteEntry(Entry<K,V> p) {
        modCount++;
        size--;

        // If strictly internal, copy successor's element to p and then make p
        // point to successor.
        if (p.left != null && p.right != null) {
            Entry<K,V> s = successor(p);
            p.key = s.key;
            p.value = s.value;
            p = s;
        } // p has 2 children
		
        // Start fixup at replacement node, if it exists.
        Entry<K,V> replacement = (p.left != null ? p.left : p.right);

        if (replacement != null) {
            // Link replacement to parent
            replacement.parent = p.parent;
            if (p.parent == null)
                root = replacement;
            else if (p == p.parent.left)
                p.parent.left  = replacement;
            else
                p.parent.right = replacement;

            // Null out links so they are OK to use by fixAfterDeletion.
            p.left = p.right = p.parent = null;

            // Fix replacement
            if (p.color == BLACK)
                fixAfterDeletion(replacement);
        } else if (p.parent == null) { // return if we are the only node.
            root = null;
        } else { //  No children. Use self as phantom replacement and unlink.
            if (p.color == BLACK)
                fixAfterDeletion(p);

            if (p.parent != null) {
                if (p == p.parent.left)
                    p.parent.left = null;
                else if (p == p.parent.right)
                    p.parent.right = null;
                p.parent = null;
            }
        }
}

官方的代码还是非常的优秀,若是能够阅读的话真的受益匪浅。

(4) 最后给出所有的代码:
①MyTreeIterator<K,V>,迭代器的实现类:

public class MyTreeIterator<K,V> implements Iterator<Entry<K,V>> {
    //private ArrayList<Entry<K,V>> arrayList;
    private Stack<Entry<K,V>> stack;
    private Entry<K,V> root;

    public MyTreeIterator(Entry<K, V> root) {
        this.root = root;
        Entry<K,V> temp = root;
        stack = new Stack<>();
        addToStack(temp);
    }
    public void addToStack(Entry<K, V> entry){
        Entry<K,V> temp = entry;
        while (temp!=null){
            stack.push(temp);
            temp = temp.getLeft();
        }
    }

    @Override
    public boolean hasNext() {
        return stack.size()>0;
    }

    @Override
    public Entry<K,V> next() {
        if(stack.size() == 0){
            throw new NoSuchElementException("迭代器中无参数了!!!");
        }
        Entry<K,V> entry = stack.pop();
        if(entry.getRight() != null){
            addToStack(entry.getRight());
        }
        return entry;
    }


    @Override
    public void remove() {

    }
}

②Entry<K,V>,节点类:

public class Entry<K,V> implements Map.Entry<K,V> {

    private Entry<K,V> left;
    private Entry<K,V> right;
    private K key;
    private V value;


    public Entry(V value) {
        this.value = value;
    }

    public Entry(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public Entry(Entry<K, V> left, Entry<K, V> right, K key, V value) {
        this.left = left;
        this.right = right;
        this.key = key;
        this.value = value;
    }

    @Override
    public K getKey() {
        return key;
    }

    @Override
    public V getValue() {
        return value;
    }

    @Override
    public V setValue(V value) {
        return value;
    }

    @Override
    public String toString() {
        return "Entry{" +
                " key=" + key +
                ", value=" + value +
                ", }";
    }

    public Entry<K, V> getLeft() {
        return left;
    }

    public void setLeft(Entry<K, V> left) {
        this.left = left;
    }

    public Entry<K, V> getRight() {
        return right;
    }

    public void setRight(Entry<K, V> right) {
        this.right = right;
    }

    public void setKey(K key) {
        this.key = key;
    }

}

③BSTree<K,V>,BSTree类:

public class BSTree<K,V> implements Iterable<Entry<K,V>>{
    private static final int MAX = 16;
    private Entry<K,V> root;
    private Comparator<K> comparator;
    private int size;
//    TreeMap


    public BSTree() {
        size = 0;
    }

    public BSTree(Comparator<K> comparator) {
        this.comparator = comparator;
        size = 0;
    }

    /**
     * compare two key how bigger if key1 more than key2 return num > 0,= 0 is someone.< 0 is letter key2.
     * if comparator is null,use comparable to equally
     * @param key1
     * @param key2
     * @return  >0 or 0 or <0
     */
    private final int compare(K key1, K key2){
        if(comparator!=null){
            return comparator.compare(key1,key2);
        }else {
            if(key1 instanceof Comparable){
                Comparable<K> k = (Comparable<K>)key1;
                return k.compareTo(key2);
            }
            throw new ClassCastException(" this class do not implement Comparable interface ");
        }
    }
    public int size(){
        return size;
    }

    /**
     * return tree entry count
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * put one key and value to this tree,in this tree create a entry to contains this key and value
     * if this tree has some key equally whit this key , this value will no replace old value , will put fail
     * @param key
     * @param value
     */
    public void put(K key,V value){
        if(root == null){
            root = new Entry<>(key,value);
            size++;
        }else {
            Entry<K,V> temp = root;
            while (temp != null){
                int sign = compare(key,temp.getKey());
                if( sign == 0 ){
                    break;
                }else if( sign > 0){
                    if(temp.getRight() != null){
                        temp = temp.getRight();
                    }else {
                        temp.setRight(new Entry<>(key,value));
                        size++;
                        break;
                    }
                }else{
                    if(temp.getLeft() != null){
                        temp = temp.getLeft();
                    }else {
                        temp.setLeft(new Entry<>(key,value));
                        size++;
                        break;
                    }
                }

            }
        }
    }

    /**
     * find this key --> entry
     * if has no this key will return null
     *
     * @param key
     * @return
     */
    private final Entry<K,V> getEntryUsingComparator(Object key) {
        if(root == null ) return null;
        if(key == null) throw new NullPointerException();
        K key1 = (K)key;
        Entry<K,V> temp = root;
        while (temp != null){
            int sign = compare(key1,temp.getKey());
            if( sign == 0 ){
                return temp;
            }else if( sign > 0){
                temp = temp.getRight();
            }else{
                temp = temp.getLeft();
            }
        }
        return null;
    }

    /**
     * return this key --> entry's value
     * @param key
     * @return
     */
    public V get(K key){
        Entry<K,V> entry = getEntryUsingComparator(key);
        if(entry != null){
            return entry.getValue();
        }
        return null;
    }
    public boolean constainKey(K key){
        return get(key) != null;
    }
    public boolean containsValue(V value){
        Iterator<Entry<K,V>> it = new MyTreeIterator<>(root);
        while (it.hasNext()){
            if(valEquals(it.next().getValue(),value)){
                return true;
            }
        }
        return false;
    }
    public final boolean valEquals(V v1,V v2){
        return v2 == null ? v1 == null : v2.equals(v1);
    }
    public Entry<K,V> getFirstEntry(Entry<K,V> entry){
        Entry<K,V> temp = entry;
        if (temp != null){
            while (temp.getLeft() != null){
                temp = temp.getLeft();
            }
        }
        return temp;
    }
    public Entry<K,V> getLastEntry(Entry<K,V> entry){
        Entry<K,V> temp = entry;
        if (temp != null){
            while (temp.getRight() != null){
                temp = temp.getRight();
            }
        }
        return temp;
    }
    public V remove(K key){
        Entry<K,V> p = getEntryUsingComparator(key);
        if(p == null)
            return null;
        V oldValue = p.getValue();
        root = deleteEntry(root,key);
        return oldValue;
    }
    private final Entry<K,V> deleteEntry(Entry<K,V> p,K key) {
        //two child

        if (p == null) {
            return null;
        }
        int compareResult = compare(p.getKey(), key);

        //如果 结果为0, 表示找到 要删除节点
        if (compareResult == 0) {
            //case 1 :
            if (p.getRight() == null && p.getLeft() == null) {
                size--;
                p = null;
            } else if (p.getLeft() != null && p.getRight() == null) {
                size--;
                p = p.getLeft();
            } else if (p.getLeft() == null && p.getRight() != null) {
                size--;
                p = p.getRight();
            } else {
                if (size % 2 == 0) {
                    //left max
                    Entry<K, V> leftMax = getLastEntry(p.getLeft());
                    //将p转为 leftMax
                    p.setKey(leftMax.getKey());
                    p.setValue(leftMax.getValue());
                    //
                    Entry<K, V> newLeft = deleteEntry(p.getLeft(), p.getKey());

                    p.setLeft(newLeft);
                } else {
                    //right min
                    Entry<K, V> rightMin = getFirstEntry(p.getRight());
                    //将p转为 rightMin
                    p.setKey(rightMin.getKey());
                    p.setValue(rightMin.getValue());
                    Entry<K, V> newRight = deleteEntry(p.getRight(), p.getKey());
                    p.setRight(newRight);
                }
            }
        } else if (compareResult < 0) {
            //未找到节点,递归调用删除p的右子树
            //将返回值作为新右子树
            Entry<K, V> newRight = deleteEntry(p.getRight(), key);
            p.setRight(newRight);
        } else {
            //未找到节点,递归调用删除p的左子树
            //将返回值作为新左子树
            Entry<K, V> newLeft = deleteEntry(p.getLeft(), key);
            p.setLeft(newLeft);
        }
        //返回新树
        return p;
    }
    public void levelOrder(){
        Queue<Entry<K,V>> queue = new LinkedList<>();
        queue.offer(root);
        int preCount = 1;
        int pCount = 0;
        while(!queue.isEmpty()){
            preCount--;

            Entry<K,V> p = queue.poll();
            System.out.print(p+"\t");
            if(p.getLeft() != null){
                queue.offer(p.getLeft());
                pCount++;
            }
            if(p.getRight() != null){
                queue.offer(p.getRight());
                pCount++;
            }
            if(preCount == 0){
                preCount = pCount;
                pCount = 0;
                System.out.println();
            }
        }
    }
//    static <K,V> TreeMap.Entry<K,V> successor(TreeMap.Entry<K,V> t) {
//             //if t is null ,return null
//        if (t == null)
//            return null;
//             //left --> root --> right print
//            //so if this entry has right child,the next entry is right tree leftes child.
//        else if (t.right != null) {
//            TreeMap.Entry<K,V> p = t.right;
//            while (p.left != null)
//                p = p.left;
//            return p;
//        } else {
//            //if this entry has no child, to father,and if this node is father right child,should find up level,
//            //until root ... if allways not found , this entry has no next.
//
//            TreeMap.Entry<K,V> p = t.parent;
//            TreeMap.Entry<K,V> ch = t;
//            while (p != null && ch == p.right) {
//                ch = p;
//                p = p.parent;
//            }
//            return p;
//        }
//    }


    @Override
    public Iterator<Entry<K,V>> iterator() {
        return new MyTreeIterator<>(root);
}
		}

好的,这就完成了一个简易的二叉搜索树了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值