Hola a todos, empecé a investigar los árboles hash como TreeMap y TreeSet, empecé a implementar el TreeMap casero, tengo el siguiente problema:
Las inserciones andan pero cuando quiero pasar de un map a otro se me borra un elemento, esto es lo que me muestra por consola:
run:
* tamaño mapa 1: 5
[5 -> Persona{5, Nombre: Maria, Edad: 18}]
[4 -> Persona{4, Nombre: Luis, Edad: 71}]
[3 -> Persona{3, Nombre: Julia, Edad: 62}]
[2 -> Persona{2, Nombre: Alberto, Edad: 73}]
[1 -> Persona{1, Nombre: Juan, Edad: 56}]
* tamaño mapa 2: 4
[5 -> Persona{5, Nombre: Maria, Edad: 18}]
[4 -> Persona{4, Nombre: Luis, Edad: 71}]
[2 -> Persona{2, Nombre: Alberto, Edad: 73}]
[1 -> Persona{1, Nombre: Juan, Edad: 56}]
Este es el código para las inserciones y para mostrar:
Código Java:
Ver originalpackage treemapsimple;
import java.util.AbstractCollection;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
*
* @author detectivejd
* @param <K>
* @param <V>
*/
public class MyTreeMap<K,V> implements Map<K, V>
{
private final Comparator<? super K> comparator;
private final boolean RED = true;
private final boolean BLACK = false;
private Entry<K,V> root;
private int size;
public MyTreeMap() {
clear();
this.comparator = null;
}
public MyTreeMap(Comparator<? super K> xcomparator) {
clear();
this.comparator = xcomparator;
}
public MyTreeMap(Map<? extends K, ? extends V> m) {
clear();
this.comparator = null;
putAll(m);
}
.......
@Override
public V put(K key, V value) {
if(key != null){
Entry<K,V> t = root;
if(t == null){
root = new Entry(key, value,null);
size = 1;
return null;
}
int cmp = 0;
Entry<K,V> parent = null;
if(comparator != null){
while (t != null) {
parent = t;
cmp = comparator.compare(key,t.key);
if(cmp < 0){
t = t.left;
} else if(cmp > 0) {
t = t.right;
} else {
t.value = value;
return value;
}
}
} else {
while (t != null) {
parent = t;
Comparable<? super K> k = (Comparable<? super K>) key;
cmp = k.compareTo(t.key);
if(cmp < 0){
t = t.left;
} else if(cmp > 0) {
t = t.right;
} else {
t.value = value;
return value;
}
}
}
Entry<K,V> e = new Entry(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
rbInsertFixup(e);
size++;
}
return null;
}
private void rbInsertFixup(Entry<K,V> x) {
x.color = RED;
while (x.parent != null && x != root && x.parent.color == RED) {
if (x.parent == x.parent.parent.left) {
// x's parent is a left child.
Entry<K,V> y = x.parent.parent.right;
if (y != null && y.color == RED) {
// Case 1: x's uncle y is red.
// System.out.println("rbInsertFixup: Case 1 left");
x.parent.color = BLACK;
y.color = BLACK;
x.parent.parent.color = RED;
x = x.parent.parent;
} else {
if (x == x.parent.right) {
// Case 2: x's uncle y is black and x is a right child.
// System.out.println("rbInsertFixup: Case 2 left");
x = x.parent;
leftRotate(x);
}
// Case 3: x's uncle y is black and x is a left child.
//System.out.println("rbInsertFixup: Case 3 left");
x.parent.color = BLACK;
x.parent.parent.color = RED;
rightRotate(x.parent.parent);
}
} else {
// x's parent is a right child. Do the same as when x's
// parent is a left child, but exchange "left" and "right."
Entry<K,V> y = x.parent.parent.left;
if (y != null && y.color == RED) {
// Case 1: x's uncle y is red.
// System.out.println("rbInsertFixup: Case 1 right");
x.parent.color = BLACK;
y.color = BLACK;
x.parent.parent.color = RED;
x = x.parent.parent;
} else {
if (x == x.parent.left) {
// Case 2: x's uncle y is black and x is a left child.
// System.out.println("rbInsertFixup: Case 2 right");
x = x.parent;
rightRotate(x);
}
// Case 3: x's uncle y is black and x is a right child.
// System.out.println("rbInsertFixup: Case 3 right");
x.parent.color = BLACK;
x.parent.parent.color = RED;
leftRotate(x.parent.parent);
}
}
}
// The root is always black.
root.color = BLACK;
}
/**
* Do a right rotation around this node.
*/
private void rightRotate(Entry<K,V> y) {
Entry<K,V> x = y.left;
y.left = x.right;
if (x.right != null)
x.right.parent = y;
x.parent = y.parent;
if (y.parent == null) {
root = (Entry)x;
} else if (y == y.parent.right){
y.parent.right = x;
} else {
x.parent.left = x;
}
x.right = y;
y.parent = x;
}
/**
* Do a left rotation around this node.
*/
private void leftRotate(Entry<K,V> x) {
Entry<K,V> y = x.right;
x.right = y.left;
if (y.left != null)
y.left.parent = x;
y.parent = x.parent;
if (x.parent == null) {
root = (Entry)y;
} else if (x == x.parent.left) {
x.parent.left = y;
} else {
x.parent.right = y;
}
y.left = x;
x.parent = y;
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
m.entrySet().forEach((e) -> {
put(e.getKey(), e.getValue());
});
}
@Override
if (root == null)
return "";
else
return print(root, 0);
}
private String print
(Entry
<K,V
> x,
int depth
) { if (x == null)
return "";
else
return print(x.right, depth + 1) +
indent(depth) + x.toString() +
"\n"+ print(x.left, depth + 1);
}
private String indent
(int s
) { for (int i = 0; i < s; i++)
result += " ";
return result;
}
}
Y este es el método que estoy probando:
Código Java:
Ver originalPersona p1 = new Persona(Persona.getMaxId(), "Juan", 56);
Persona.maxIdUp();
Persona p2 = new Persona(Persona.getMaxId(), "Alberto", 73);
Persona.maxIdUp();
Persona p3 = new Persona(Persona.getMaxId(), "Julia", 62);
Persona.maxIdUp();
Persona p4 = new Persona(Persona.getMaxId(), "Luis", 71);
Persona.maxIdUp();
Persona p5 = new Persona(Persona.getMaxId(), "Maria", 18);
Persona.maxIdUp();
Persona p6 = new Persona(Persona.getMaxId(), "Pedro", 16);
Persona.maxIdUp();
Persona p7 = new Persona(Persona.getMaxId(), "Deborah", 26);
Persona.maxIdUp();
Persona p8 = new Persona(Persona.getMaxId(), "Nelson", 37);
Persona.maxIdUp();
Persona p9 = new Persona(Persona.getMaxId(), "Tommy", 22);
Persona.maxIdUp();
Persona p10 = new Persona(Persona.getMaxId(), "Manuela", 15);
Persona.maxIdUp();
MyTreeMap
<Integer,Persona
> map
= new MyTreeMap
(); map.put(p1.getId(), p1);
map.put(p2.getId(), p2);
map.put(p3.getId(), p3);
map.put(p4.getId(), p4);
map.put(p5.getId(), p5);
MyTreeMap
<Integer,Persona
> map2
= new MyTreeMap
(map
); //map2.put(p6.getId(), p6);
//map2.put(p7.getId(), p7);
//map2.put(p8.getId(), p8);
//map2.put(p9.getId(), p9);
//map2.put(p10.getId(), p10);
System.
out.
println("* tamaño mapa 1: " + map.
size()); System.
out.
println(map.
toString()); System.
out.
println("* tamaño mapa 2: " + map2.
size()); System.
out.
println(map2.
toString()); }
Hace unos días que no le encuentro la vuelta a esto, espero sus respuestas y saludos.
PD: Todavía no lo subí a github.