简单实现TreeMap

本文介绍了如何自定义TreeMap的节点结构,包括键、值、左右子节点,并详细阐述了重写equals()和hashCode()方法的原因。此外,还讨论了TreeMap中的size、root和comparator属性,以及put()方法的实现逻辑。最后,提到了迭代器的使用,并提供了测试案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 实现TreeMap的结点
    说明:
    1. 结点包含 键 值 左孩子结点 右孩子结点
    2. 后面重写的equals() 和 hashCode() 方法是为了方便后期的测试
 /**
     * 定义结点
     * @param <K> 键
     * @param <V> 值
     */
    class TreeNode<K, V> implements Map.Entry<K, V>{

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

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

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

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

        public TreeNode(K key, V value) {
            this(key, value, null, null);
        }

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

        @Override
        public String toString() {
            return "AVLEntry{" +
                    "key=" + key +
                    ", value=" + value +
                    ", left=" + left +
                    ", right=" + right +
                    '}';
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            TreeNode<?, ?> treeNode = (TreeNode<?, ?>) o;

            if (key != null ? !key.equals(treeNode.key) : treeNode.key != null) return false;
            if (value != null ? !value.equals(treeNode.value) : treeNode.value != null) return false;
            if (left != null ? !left.equals(treeNode.left) : treeNode.left != null) return false;
            return right != null ? right.equals(treeNode.right) : treeNode.right == null;
        }

        @Override
        public int hashCode() {
            int result = key != null ? key.hashCode() : 0;
            result = 31 * result + (value != null ? value.hashCode() : 0);
            result = 31 * result + (left != null ? left.hashCode() : 0);
            result = 31 * result + (right != null ? right.hashCode() : 0);
            return result;
        }
	}
  1. 自定义TreeMap所需的属性
    说明:1. size 是树中拥有的元素个数
    2. root 根节点
    3. comparator 因为TreeMap是要求按一定的顺序进行存储的,所以需要一个比较器来进行自定义对象的比较规则
    private int size;
    private TreeNode<K, V> root;
    private Comparator<K> comparator;

    public int compar(K a, K b){
        if (comparator != null){
            return comparator.compare(a, b);
        }else {
            Comparable<K> temp = (Comparable<K>) a;
            return temp.compareTo(b);
        }
    }
  1. put() 方法
    说明 1. 在对键进行比较后如果返回值是0,表明两个键相等,那么只需更新这个键所对应的值
    public V put(K key, V value){
        if (root == null){
            root = new TreeNode<>(key, value);
            size++;
        }else {
            TreeNode<K, V> temp = root;
            while (temp != null){
                int flag = compar(key, temp.key);
                if (flag == 0){
                    temp.setValue(value);
                    break;
                }else if (flag < 0){
                    if (temp.left == null){
                        temp.left = new TreeNode<>(key, value);
                        size++;
                        break;
                    }else {
                        temp = temp.left;
                    }
                }else if (flag > 0){
                    if (temp.right == null){
                        temp.right = new TreeNode<>(key, value);
                        size++;
                        break;
                    }else {
                        temp = temp.right;
                    }
                }
            }
        }
        return value;
    }
  1. 迭代器
    /**
     * 迭代器
     */
    private class MyIterator implements Iterator<TreeNode<K, V>>{

        private Iterator<TreeNode<K, V>> iterator;

        public MyIterator(){
            List<TreeNode<K, V>> list = new ArrayList<>();
            inOrder(root, list);
            iterator = list.iterator();
        }

        //先序遍历
        private void inOrder(TreeNode<K, V> root, List<TreeNode<K, V>> list){
            if (root != null){
                inOrder(root.left, list);
                list.add(root);
                inOrder(root.right, list);
            }
        }

        @Override
        public boolean hasNext() {
            return iterator.hasNext();
        }

        @Override
        public TreeNode<K, V> next() {
            return iterator.next();
        }

        @Override
        public void remove() {
            iterator.remove();
        }
    }
  1. 测试部分
package com.dgy.tree;

import org.junit.Test;

import java.util.*;

/**
 * Date: 2019/7/30
 * Time: 10:50
 * Author: vincent-Dou
 * Description:
 */
public class TestMyMap {
    @Test
    public void test1(){
        MyMap<Integer, String> map = new MyMap<>();
//        TreeMap<Integer, String> map = new TreeMap<>();
        map.put(3, "I");
        map.put(1, "hello");
        map.put(2, "world");
        map.put(5, "豆光耀");
        map.put(4, "am");
        Iterator iterator = map.iterator();
        while (iterator.hasNext()){
            System.out.println(((MyMap.TreeNode)iterator.next()).getValue());
        }
    }



    @Test
    public void test2(){
        Random random = new Random();
        int sum = 65535;
        Map<Integer, String> map1 = new TreeMap<>();
        MyMap<Integer, String> map2 = new MyMap<>();
        int coun = 0;
        for (int i = 0; i < sum; i++){
            int key = random.nextInt(sum);
            String value = String.valueOf(key);
            map1.put(key, value);
            map2.put(key, value);
            System.out.println("成功添加:"+(coun++)+"个");
        }
        Iterator iterator1 = map1.entrySet().iterator();
        Iterator iterator2 = map2.iterator();
        int count = 0;
        while (iterator1.hasNext() && iterator2.hasNext()){
            if (!iterator1.next().equals(iterator2.next())){
                System.out.println("不匹配有问题");
            }
            System.out.println("成功比对:"+(count++)+"个");
        }
        System.out.println("成功完成所有元素对比");
    }


    class Student{
        Integer age;
        String name;

        public Student(Integer age, String name) {
            this.age = age;
            this.name = name;
        }

        @Override
        public String toString() {
            return "Student{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    @Test
    public void test3(){
        MyMap<Student, Integer> myMap = new MyMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                if (!(o1 instanceof Student  &&  o2 instanceof Student)){
                    throw new IllegalArgumentException("两个对象无法进行比较");
                }
                Student temp1 = (Student) o1;
                Student temp2 = (Student) o2;
                int flag = temp1.age.compareTo(temp2.age);
                if (flag == 0){
                    return temp1.name.compareTo(temp2.name);
                }
                return flag;
            }
        });
        Student student1 = new Student(20, "AA");
        Student student2 = new Student(25, "AA");
        Student student3 = new Student(19, "AA");
        Student student4 = new Student(23, "AA");
//        Student student5 = new Student(23, "AA");
        myMap.put(student1,10);
        myMap.put(student2,10);
        myMap.put(student3,10);
        myMap.put(student4,10);
//        myMap.put(student5,10);
        Iterator iterator = myMap.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println(myMap.size());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值