一、集合
集合的特点就是不存放重复的元素,如果集合底层用链表实现,那么集合的添加、删除、查找时间复杂度都是O(n),这里可能会有疑问,链表的添加时间复杂度不是O(1)吗?是的,但是注意集合的特点就是不存放重复的元素,所以集合在添加的时候会去遍历一遍链表,看看有没有相同的元素,所以集合使用链表实现时,时间复杂度是O(n)。集合使用红黑树时,那么它的时间复杂度是O(logn)。但是使用红黑树实现,那么元素必须具备可比较性,这个就是限制。如何解决这个问题呢?就是后面的经典数据结构哈希表,HashMap!
链表实现:
public class ListSet<E> implements Set<E> {
private List<E> list = new LinkedList<>();
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public void clear() {
list.clear();
}
@Override
public boolean contains(E element) {
return list.contains(element);
}
@Override
public void add(E element) {
// //第一种做法:遇到重复元素直接return
// if (list.contains(element)) return;
// list.add(element);
int index = list.indexOf(element);
if (index != List.ELEMENT_NOT_FOUND) { //存在就覆盖
list.set(index, element);
} else { //不存在就加进去
list.add(element);
}
}
@Override
public void remove(E element) {
int index = list.indexOf(element);
if (index != List.ELEMENT_NOT_FOUND) { //存在才删除
list.remove(index);
}
}
@Override
public void traversal(Visitor visitor) {
if (visitor == null) return;
int size = list.size();
for (int i = 0; i < size; i++) {
if (visitor.visit(list.get(i))) return;
}
}
}
红黑树实现:
public class TreeSet<E> implements Set<E> {
private RBTree<E> tree = new RBTree<>();
@Override
public int size() {
return tree.size();
}
@Override
public boolean isEmpty() {
return tree.isEmpty();
}
@Override
public void clear() {
tree.clear();
}
@Override
public boolean contains(E element) {
return tree.contains(element);
}
@Override
public void add(E element) {
//红黑树本身就对重复的元素有处理逻辑: 如果相同就覆盖,否则就加上去
tree.add(element);
}
@Override
public void remove(E element) {
tree.remove(element);
}
@Override
public void traversal(Visitor<E> visitor) {
//这里用中序遍历
tree.inorder(new BinaryTree.Visitor<E>() { //套娃: 在二叉树里面的Visitor 调用 集合里面的Visitor
@Override
public boolean visit(E element) {
return visitor.visit(element);
}
});
}
}