基于二分搜索树的集合实现(Set)
不能添加重复元素
集合是有序的,效率高
interface Set<E>{
void add(E e);
void remove(E e);
boolean contains(E e);
int getSize();
boolean isEmpty();
}
class BSTSet<E extends Comparable<E>> implements Set<E>{
private BinarySearchTree bst;
public BSTSet(){
bst = new BinarySearchTree();
}
@Override
public int getSize(){
return bst.size();
}
@Override
public boolean isEmpty(){
return bst.isEmpty();
}
@Override
public void add(E e){
bst.add(e);
}
@Override
public void remove(E e){
bst.remove(e);
}
@Override
public boolean contains(E e){
return bst.contains(e);
}
}
class BinarySearchTree<E extends Comparable<E>> {
private class Node{
public E e;
public Node leftNext;
public Node rightNext;
private Node(E e){
this.e = e;
leftNext = null;
rightNext = null;
}
}
private Node root;
private int size;
public BinarySearchTree(){
root = null;
size = 0;
}
public int size(){
return size;
}
public boolean isEmpty(){
return size == 0;
}
public void add(E e) {
root = add(root, e);
}
private Node add(Node root, E e){
if (root == null){
size++;
return new Node(e);
}
if (root.e.compareTo(e) < 0){
root.rightNext = add(root.rightNext, e);
}
else if (root.e.compareTo(e) > 0) {
root.leftNext = add(root.leftNext, e);
}
return root;
}
public E removeMin(){
E value = Min();
root = removeMin(root);
return value;
}
private Node removeMin(Node root){
if (root.leftNext == null){
Node newRoot = root.rightNext;
root.rightNext = null;
size--;
return newRoot;
}
root.leftNext = removeMin(root.leftNext);
return root;
}
public void remove(E e){
root = remove(root, e);
}
private Node remove(Node root, E e){
if (root == null){
return null;
}
if (root.e.compareTo(e) < 0){
root.rightNext = remove(root.rightNext, e);
return root;
}
else if (root.e.compareTo(e) > 0){
root.leftNext = remove(root.leftNext, e);
return root;
}
else {
if (root.leftNext == null) {
Node newRoot = root.rightNext;
root.rightNext = null;
size--;
return newRoot;
} else if (root.rightNext == null) {
Node newRoot = root.leftNext;
root.leftNext = null;
size--;
return newRoot;
} else {
Node newRoot = Min(root.rightNext);
newRoot.rightNext = removeMin(root.rightNext);
newRoot.leftNext = root.leftNext;
root.leftNext = null;
root.rightNext = null;
return newRoot;
}
}
}
public boolean contains(E e){
return contains(root, e);
}
private boolean contains(Node root, E e){
if (root == null) {
return false;
}
if (root.e.compareTo(e) == 0){
return true;
}
else if (root.e.compareTo(e) > 0){
return contains(root.leftNext, e);
}
else {
return contains(root.rightNext, e);
}
}
public E Min(){
return Min(root).e;
}
private Node Min(Node root){
if (root == null){
return null;
}
if (root.leftNext == null){
return root;
}
return Min(root.leftNext);
}
}
基于链表的集合实现
集合是无序的
interface Set<E>{
void add(E e, int index);
void remove(int index);
boolean contains(E e);
int getSize();
boolean isEmpty();
}
class LinkedListSet<E> implements Set<E>{
private LinkedList linkedList;
public LinkedListSet(){
linkedList = new LinkedList<>();
}
@Override
public int getSize(){
return linkedList.size();
}
@Override
public boolean isEmpty(){
return linkedList.isEmpty();
}
@Override
public void add(E e, int index){
if (!linkedList.contains(e)) {
linkedList.add(e, index);
}
}
@Override
public void remove(int index){
linkedList.remove(index);
}
@Override
public boolean contains(E e){
return linkedList.contains(e);
}
}
class LinkedList<E>{
class Node{
public E e;
public Node next;
public Node(E e, Node next){
this.e = e;
this.next = next;
}
public Node(){
this.next = null;
}
}
private Node dummyHead;
private int size;
public LinkedList(){
dummyHead = new Node();
size = 0;
}
public int size(){
return size;
}
public boolean isEmpty(){
return isEmpty();
}
private Node getPrevNode(int index){
if (index < 0 || index > size){
throw new IllegalArgumentException("索引不合法");
}
if (index == 0){
return dummyHead;
}
return getPrevNode(index - 1).next;
}
public void add(E e, int index){
Node prev = getPrevNode(index);
prev.next = new Node(e, prev.next);
size++;
}
public E remove(int index){
if (index == size){
throw new IllegalArgumentException("索引不合法");
}
Node prev = getPrevNode(index);
Node temp = prev.next;
prev.next = temp.next;
temp.next = null;
size--;
return temp.e;
}
public boolean contains(E e){
for (Node prev = dummyHead; prev.next != null; prev = prev.next) {
if (prev.next.e.equals(e)){
return true;
}
}
return false;
}
}
基于链表的映射实现(Map)
存储(键,值)数据对的数据结构,根据键寻找值
无序
interface Map<K, V>{
void add(K key, V value);
V remove(K key);
boolean contains(K key);
V get(K key);
void set(K key, V value);
int getSize();
boolean isEmpty();
}
class LinkedListMap<K, V> implements Map<K, V>{
class Node{
public K key;
public V value;
public Node next;
public Node(K key, V value, Node next){
this.key = key;
this.value = value;
this.next = next;
}
public Node(){
this(null, null, null);
}
}
private Node dummyHead;
private int size;
public LinkedListMap(){
dummyHead = new Node();
size = 0;
}
@Override
public int getSize(){
return size;
}
@Override
public boolean isEmpty(){
return size == 0;
}
private Node getNode(K key){
Node cur = dummyHead.next;
while (cur != null){
if (cur.key.equals(key)){
return cur;
}
cur = cur.next;
}
return null;
}
@Override
public boolean contains(K key){
return getNode(key) != null;
}
@Override
public V get(K key){
Node res = getNode(key);
return res == null ? null : res.value;
}
@Override
public void add(K key, V value){
Node res = getNode(key);
if (res == null){
dummyHead.next = new Node(key, value, dummyHead.next);
}
res.value = value;
}
@Override
public void set(K key, V value) {
Node res = getNode(key);
if (res == null){
throw new IllegalArgumentException("没有这个键");
}
res.value = value;
}
@Override
public V remove(K key){
Node prev = dummyHead;
while (prev.next != null){
if (prev.next.key.equals(key)){
Node temp = prev.next;
prev.next = temp.next;
temp.next = null;
size--;
return temp.value;
}
prev = prev.next;
}
return null;
}
}
拓展:用哈希表实现的无序集合和映射,效率比二分搜索树更高
基于二分搜索树的映射实现
有序,效率高
interface Map<K, V>{
void add(K key, V value);
V remove(K key);
boolean contains(K key);
V get(K key);
void set(K key, V value);
int getSize();
boolean isEmpty();
}
class BSTMap<K extends Comparable<K>, V> implements Map<K, V>{
class Node{
public K key;
public V value;
public Node leftNext;
public Node rightNext;
public Node(K key, V value){
this.key = key;
this.value = value;
leftNext = null;
rightNext = null;
}
}
private Node root;
private int size;
public BSTMap(){
root = null;
size = 0;
}
@Override
public int getSize(){
return size;
}
@Override
public boolean isEmpty(){
return size == 0;
}
private Node getNode(Node root, K key){
if (root == null){
return null;
}
if (root.key.compareTo(key) == 0){
return root;
}
else if (root.key.compareTo(key) > 0){
return getNode(root.leftNext, key);
}
else {
return getNode(root.rightNext, key);
}
}
@Override
public boolean contains(K key){
return getNode(root, key) != null;
}
@Override
public V get(K key){
Node res = getNode(root, key);
return res == null ? null : res.value;
}
@Override
public void add(K key, V value){
root = add(root, key, value);
}
private Node add(Node root, K key, V value){
if (root == null){
size++;
return new Node(key, value);
}
if (root.key.compareTo(key) > 0){
root.leftNext = add(root.leftNext, key, value);
}
else if (root.key.compareTo(key) < 0){
root.rightNext = add(root.rightNext, key, value);
}
else {
root.value = value;
}
return root;
}
@Override
public void set(K key, V value) {
Node res = getNode(root, key);
if (res == null){
throw new IllegalArgumentException("键值不存在");
}
else {
res.value = value;
}
}
private Node Min(Node root){
if (root.leftNext == null){
return root;
}
return Min(root.leftNext);
}
private Node removeMin(Node root){
if (root.leftNext == null){
Node newRoot = root.rightNext;
root.rightNext = null;
size--;
return newRoot;
}
root.leftNext = removeMin(root.leftNext);
return root;
}
@Override
public V remove(K key){
Node res = getNode(root, key);
if (res == null){
throw new IllegalArgumentException("键值不存在");
}
root = remove(root, key);
return res.value;
}
private Node remove(Node root, K key){
if (root.key.compareTo(key) > 0){
root.leftNext = remove(root.leftNext, key);
return root;
}
else if (root.key.compareTo(key) < 0){
root.rightNext = remove(root.rightNext, key);
return root;
}
else {
if (root.leftNext == null) {
Node newRoot = root.rightNext;
root.rightNext = null;
size--;
return newRoot;
}
else if (root.rightNext == null) {
Node newRoot = root.leftNext;
root.leftNext = null;
size--;
return newRoot;
}
else {
Node min = Min(root.rightNext);
min.rightNext = removeMin(root.rightNext);
min.leftNext = root.leftNext;
root.leftNext = null;
root.rightNext = null;
return min;
}
}
}
}
复杂度分析
对于链表实现的集合或者映射,add()、remove()、contains()方法的时间复杂度为O(n)
而对于二分搜索树实现的集合,如果树的深度为h,则复杂度为O(h),平均情况时也即O(logn),但在极端情况下,会退化成链表,解决方法是引入平衡二叉树