1,常用数据结构
List:有序的线性存储结构;
Set:元素不重复的存储结构,JDK有基于HashMap和TreeMap分别实现无序和有序Set;
Queue:先进先出的存储结构;
Stack:先进后出的存储结构;
Map:Key-Value存储结构;
Tree:树状存储结构;本文不展开分析此类
2,ArrayList和LinkedList简单实现
(1)ArrayList核心思想是利用数组,动态扩展大小;最大为2^32。通过数据实现,查找/修改时间复杂度为O(1)是删除/增加为O(n)
package _数据结构._List;
import java.util.*;
/**
* @program: suanfa_by_java
* @author: 一树
* @data: 2020/11/14 19:21
*/
//实现可迭代接口
public class MyArrayList<T> implements Iterable<T> {
private static final int DEFAULT_CAPACITY = 10;
private int size;
private T[] Items;
public MyArrayList() {
doInit();
ensureCapacity(DEFAULT_CAPACITY);
}
public MyArrayList(int initCapacity) {
doInit();
ensureCapacity(initCapacity);
}
public MyArrayList(Collection<? extends T> c) {
doInit();
ensureCapacity(DEFAULT_CAPACITY);
for (T t : c) {
this.add(t);
}
}
@SuppressWarnings("unchecked")
public void clear() {
doInit();
Items = (T[]) new Object[DEFAULT_CAPACITY];
}
public int size() {
return size;
}
private void doInit() {
this.size = 0;
}
@SuppressWarnings("unchecked")
private void ensureCapacity(int newCapacity) {
if (newCapacity < 0) {
throw new IllegalArgumentException("newCapacity < 0");
}
if (newCapacity < size) return;
T[] old = Items;
Items = (T[]) new Object[newCapacity];
for (int i = 0; i < size(); i++) {
Items[i] = old[i];
}
}
public T set(int index, T value) {
checkIndex(index);
T old = Items[index];
Items[index] = value;
return old;
}
public T get(int index) {
checkIndex(index);
return Items[index];
}
public void add(T value) {
if (size() == Items.length) {
//扩容
ensureCapacity(2 * size() + 1);
}
Items[size()] = value;
size++;
}
//消费者模式,只可读不可写的泛型限定
public void addAll(Collection<? extends T> c) {
for (T t : c) {
this.add(t);
}
}
public void remove(int index) {
checkIndex(index);
for (int i = index; i < size() - 1; i++) {
Items[i] = Items[i + 1];
}
size--;
}
private void checkIndex(int index) {
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException();
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < size; i++) {
sb.append(Items[i]);
sb.append(',');
}
sb.delete(sb.length() - 1, sb.length());
sb.append(']');
return sb.toString();
}
@SuppressWarnings("unchecked")
public void sort(Comparator<? super T> c) {
T[] a = (T[]) new Object[size];
for (int i = 0; i < size; i++) {
a[i] = Items[i];
}
Arrays.sort(a, c);
for (int i = 0; i < size; i++) {
Items[i] = a[i];
}
}
@Override
public Iterator<T> iterator() {
return new ArrayListIterator();
}
// 具体可迭代的实现者接口
private class ArrayListIterator implements java.util.Iterator<T> {
private int current = 0;
@Override
public boolean hasNext() {
return current < size;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return (T) Items[current++];
}
@Override
public void remove() {
MyArrayList.this.remove(--current);
}
}
}
(2)LinkedList,利用链表实现。查找/修改时间复杂度为O(n),删除/增加复杂度为O(1);
package _数据结构._List;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* @program: suanfa_by_java
* @author: 一树
* @data: 2020/11/15 10:34
*/
public class MyLinkedList<T> implements Iterable<T>{
private int size;
private Node<T> beginMarker;
private Node<T> endMarker;
public MyLinkedList() {
doInit();
}
public MyLinkedList(Collection<? extends T> c) {
doInit();
for (T t : c) {
add(t);
}
}
private void doInit() {
size = 0;
}
public void addAll(Collection<? extends T> others) {
for (T other : others) {
add(other);
}
}
//双链表
private class Node<T> {
T value;
Node<T> next;
Node<T> prefix;
public Node(T value) {
this.value = value;
}
}
private Node<T> getNode(int index) {
checkIndex(index);
Node<T> p;
int cnt = 0;
int limit = size - 1;
if (index <= limit / 2) {
p = beginMarker;
while (cnt < index) {
cnt++;
p = p.next;
}
return p;
} else {
p = endMarker;
while (cnt < index) {
cnt++;
p = p.prefix;
}
return p;
}
}
private boolean deleteNode(int index) {
checkIndex(index);
if (index > 0 && index < size - 1) {
Node<T> node = getNode(index);
Node<T> prefix = node.prefix;
Node<T> next = node.next;
prefix.next = next;
next.prefix = prefix;
node.next = null;
node.prefix = null;
return true;
}
if (index == 0) {
Node<T> node = this.beginMarker;
Node<T> next = node.next;
next.prefix = null;
beginMarker = next;
node.next = null;
}
if (index == size - 1) {
Node<T> node = this.endMarker;
Node<T> prefix = node.prefix;
prefix.next = null;
node.prefix = null;
endMarker = prefix;
return true;
}
return false;
}
private boolean insertNode(int index, Node<T> node) {
if (size == 0) {
beginMarker = node;
endMarker = node;
return true;
}
if (index > 0 && index < size - 1) {
Node<T> nextNode = getNode(index);
Node<T> preNode = nextNode.prefix;
preNode.next = node;
node.prefix = preNode;
nextNode.prefix = node;
node.next = nextNode;
return true;
}
if (index == 0) {
beginMarker.prefix = node;
node.next = beginMarker;
beginMarker = node;
return true;
}
if (index == size) {
endMarker.next = node;
node.prefix = endMarker;
endMarker = node;
return true;
}
return false;
}
private void checkIndex(int index) {
if (index < 0 || index >= size)
throw new ArrayIndexOutOfBoundsException();
}
public void add(T t) {
this.insertNode(size, new Node<T>(t));
size++;
}
public void remove(int index) {
this.deleteNode(index);
size--;
}
public T get(int index) {
return getNode(index).value;
}
public T set(int index, T newValue) {
Node<T> node = getNode(index);
T old = node.value;
node.value = newValue;
return old;
}
public int size() {
return size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Iterator<T> iterator = iterator();
sb.append('[');
while (iterator.hasNext()) {
sb.append(iterator.next());
sb.append(',');
}
sb.delete(sb.length() - 1, sb.length());
sb.append(']');
return sb.toString();
}
/**
* 迭代器接口
*/
@Override
public Iterator<T> iterator() {
return new LinkedListIterator();
}
private class LinkedListIterator implements java.util.Iterator<T> {
Node<T> current = beginMarker;
@Override
public boolean hasNext() {
return current != null;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
T nextItem = current.value;
current = current.next;
return nextItem;
}
@Override
public void remove() {
MyLinkedList.this.remove(MyLinkedList.this.size - 1);
}
}
}
3,HashMap简单实现
通过查看HashMap源码,可知核心有散列表、扩若阀值等;
判断两个元素是否相等,通过hash值和equal联合判断;
在JDK规范中,hash相等,equal不一定相等;
hash相等而equal不等就属于hash冲突,jdk采用链表解决hash冲突;即每个散列表中存储的元素都是一个双链表;
package _数据结构._Map;
import java.util.*;
/**
* @program: suanfa_by_java
* @author: 一树
* @data: 2020/11/16 9:49
*/
public class MyHashMap<K, V> {
private static final int DEFAULT_CAPACITY = 17;
private static final float DEFAULT_LOAD = 0.75f;
private static final int MAX_CAPACITY = (1 << 30) + 1;
private int size;
private int resizeCount;
private Node<K, V>[] table;
private int tableLength;
private float load;
@SuppressWarnings("unchecked")
public MyHashMap(int capacity, float load) {
this.tableLength = capacity;
this.load = load;
this.table = (Node<K, V>[]) new Node[capacity];
}
@SuppressWarnings("unchecked")
public MyHashMap(int capacity) {
this.tableLength = capacity;
this.load = DEFAULT_LOAD;
this.table = (Node<K, V>[]) new Node[capacity];
}
@SuppressWarnings("unchecked")
public MyHashMap() {
this.load = DEFAULT_LOAD;
this.tableLength = DEFAULT_CAPACITY;
this.table = (Node<K, V>[]) new Node[tableLength];
}
@SuppressWarnings("unchecked")
public MyHashMap(Map<? extends K, ? extends V> map) {
this.load = DEFAULT_LOAD;
this.tableLength = DEFAULT_CAPACITY;
this.table = (Node<K, V>[]) new Node[tableLength];
for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
put(key, value);
}
}
/*扩容*/
@SuppressWarnings("unchecked")
private void resize() {
int newCapacity = Math.min(MAX_CAPACITY, (tableLength << 1) + 1);
Node<K, V>[] oldTable = this.table;
this.table = (Node<K, V>[]) new Node[newCapacity];
this.tableLength = newCapacity;
//将oldItem中的数重新散列
for (Node<K, V> p : oldTable) {
while (p != null) {
K key = p.getKey();
V value = p.getValue();
put(key, value);
p = p.next;
}
}
}
public void put(K k, V v) {
this.putVal(k, v, hash(k, tableLength), false);
}
public void putIfAbsent(K k, V v) {
this.putVal(k, v, hash(k, tableLength), true);
}
private void putVal(K k, V v, int hash, boolean abSent) {
Node<K, V> p = table[hash];
Node<K, V> pre = null;
while (p != null) {
if (p.key.equals(k)) {
if (!abSent) p.value = v;
return;
}
pre = p;
p = p.next;
}
p = new Node<>(hash, k, v, null);
if (pre == null) {
table[hash] = p;
resizeCount++;//记录表被占用的数
} else {
pre.next = p;
}
size++;
if (resizeCount >= load * tableLength) {
resize();
}
}
public int size() {
return size;
}
public V get(K k) {
Node<K, V> p = table[hash(k, tableLength)];
while (p != null) {
if (k.equals(p.key)) return p.value;
p = p.next;
}
return null;
}
public void remove(K k) {
int index = hash(k, tableLength);
Node<K, V> p = table[index];
Node<K, V> pre = null;
while (p != null) {
if (k.equals(p.key)) {
Node<K, V> next = p.next;
if (next != null && pre != null) {
pre.next = next;
p.next = null;
size--;
return;
}
if (next == null && pre != null) {
pre.next = null;
size--;
return;
}
if (pre == null) {
table[index] = null;
size--;
return;
}
}
pre = p;
p = p.next;
}
}
public V set(K k, V v) {
V old = get(k);
put(k, v);
return old;
}
public boolean containKey(K k) {
return get(k) != null;
}
//散列函数
private static int hash(Object key, int tableSize) {
String h = key.toString();
int hash = 0;
for (int i = 0; i < h.length(); i++) {
hash = 37 * hash + h.charAt(i);
}
hash %= tableSize;
if (hash < 0)
hash += tableSize;
return hash;
}
/*>>>>>>>>>>>>>>>>>>>>>>>>>>class Node>>>>>>>>>>>>>>>>>>>>>>*/
public static class Node<K, V> {
int hash;
K key;
V value;
Node<K, V> next;
Node(int hash, K key, V value, Node<K, V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
/*>>>>>>>>>>>>>>>>>>>Iterator>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
public Set<Node<K, V>> enterSet() {
Set<Node<K, V>> entrySet = new HashSet<>();
//将数据装入set中
for (int i = 1; i < tableLength; i++) {
if (table[i] != null) {
Node<K, V> p = table[i];
while (p != null) {
entrySet.add(p);
p = p.next;
}
}
}
return entrySet;
}
public Set<K> enterKey() {
Set<K> entryKey = new HashSet<>();
//将数据装入set中
for (int i = 1; i < tableLength; i++) {
if (table[i] != null) {
Node<K, V> p = table[i];
while (p != null) {
entryKey.add(p.key);
p = p.next;
}
}
}
return entryKey;
}
public Set<V> enterValue() {
Set<V> entryValue = new HashSet<>();
//将数据装入set中
for (int i = 1; i < tableLength; i++) {
if (table[i] != null) {
Node<K, V> p = table[i];
while (p != null) {
entryValue.add(p.value);
p = p.next;
}
}
}
return entryValue;
}
}
4,Queue简单实现
先进先出的数据结构,采用链表简单实现;
package _数据结构._Queue;
import java.util.EmptyStackException;
/**
* @program: suanfa_by_java
* @author: 一树
* @data: 2020/11/15 15:10
*/
public class LinkedQueue<T> {
private Node<T> first;
private Node<T> end;
private int size;
private class Node<T> {
T val;
Node<T> next;
Node<T> pre;
Node() {
}
Node(T val) {
this.val = val;
}
}
public LinkedQueue() {
doInit();
}
private void doInit() {
size = 0;
first = new Node<>();
end = new Node<>();
first.next = end;
end.pre = first;
}
public boolean offer(T val) {
Node<T> node = new Node<>(val);
Node<T> pre = end.pre;
pre.next = node;
node.pre = pre;
node.next = end;
end.pre = node;
size++;
return true;
}
public T poll() {
if (size == 0) {
throw new EmptyStackException();
}
Node<T> t = first.next;
T val = t.val;
t.next.pre = first;
first.next = t.next;
t.next = null;
t.pre = null;
size--;
return val;
}
public boolean isEmpty() {
return size == 0;
}
public T peek() {
if (size == 0) {
throw new EmptyStackException();
}
return first.next.val;
}
}
5,Stack简单实现
先进后出的数据结构,有Array和Link两种实现
(1)ArrayStack
package _数据结构._Stack;
import java.util.Collection;
import java.util.EmptyStackException;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* @program: suanfa_by_java
* @author: 一树
* @data: 2020/11/15 13:47
*/
public class ArrayStack<T> implements Iterable<T> {
private static final int DEFAULT_CAPACITY = 10;
private int size;
private T[] Items;
public ArrayStack() {
doInit();
ensureCapacity(DEFAULT_CAPACITY);
}
public ArrayStack(int initCapacity) {
doInit();
ensureCapacity(initCapacity);
}
public ArrayStack(Collection<? extends T> c) {
doInit();
ensureCapacity(DEFAULT_CAPACITY);
for (T t : c) {
this.push(t);
}
}
@SuppressWarnings("unchecked")
public void clear() {
doInit();
Items = (T[]) new Object[DEFAULT_CAPACITY];
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
private void doInit() {
this.size = 0;
}
@SuppressWarnings("unchecked")
private void ensureCapacity(int newCapacity) {
if (newCapacity < 0) {
throw new IllegalArgumentException("newCapacity < 0");
}
if (newCapacity < size) return;
T[] old = Items;
Items = (T[]) new Object[newCapacity];
for (int i = 0; i < size(); i++) {
Items[i] = old[i];
}
}
public T set(int index, T value) {
checkIndex(index);
T old = Items[index];
Items[index] = value;
return old;
}
public T peek() {
return Items[size - 1];
}
public void push(T value) {
if (size() == Items.length) {
//扩容
ensureCapacity(2 * size() + 1);
}
Items[size()] = value;
size++;
}
public T pop() {
if (size == 0)
throw new EmptyStackException();
return Items[--size];
}
private void checkIndex(int index) {
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException();
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < size; i++) {
sb.append(Items[i]);
sb.append(',');
}
sb.delete(sb.length() - 1, sb.length());
sb.append(']');
return sb.toString();
}
@Override
public Iterator<T> iterator() {
return new ArrayStackIterator();
}
private class ArrayStackIterator implements java.util.Iterator<T> {
private int current = 0;
@Override
public boolean hasNext() {
return current < size;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return (T) Items[current++];
}
@Override
public void remove() {
ArrayStack.this.pop();
}
}
}
(2)LinkedStack
package _数据结构._Stack;
import java.util.Collection;
import java.util.EmptyStackException;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* @program: suanfa_by_java
* @author: 一树
* @data: 2020/11/15 14:18
*/
public class LinkedStack<T> implements Iterable<T> {
private int size;
private Node<T> beginMarker;
private Node<T> endMarker;
public LinkedStack() {
doInit();
}
public LinkedStack(Collection<? extends T> c) {
doInit();
for (T t : c) {
push(t);
}
}
private void doInit() {
size = 0;
}
public void pushAll(Collection<? extends T> others) {
for (T other : others) {
push(other);
}
}
//内部类
private class Node<T> {
T value;
Node<T> next;
Node<T> prefix;
public Node(T value) {
this.value = value;
}
}
private Node<T> getNode(int index) {
checkIndex(index);
Node<T> p;
int cnt = 0;
int limit = size - 1;
if (index <= limit / 2) {
p = beginMarker;
while (cnt < index) {
cnt++;
p = p.next;
}
return p;
} else {
p = endMarker;
while (cnt < index) {
cnt++;
p = p.prefix;
}
return p;
}
}
private T deleteEndNode() {
Node<T> node = this.endMarker;
Node<T> prefix = node.prefix;
T value = node.value;
if (prefix != null) prefix.next = null;
node.prefix = null;
endMarker = prefix;
return value;
}
private boolean insertNode(int index, Node<T> node) {
if (size == 0) {
beginMarker = node;
endMarker = node;
return true;
}
if (index > 0 && index < size - 1) {
Node<T> nextNode = getNode(index);
Node<T> preNode = nextNode.prefix;
preNode.next = node;
node.prefix = preNode;
nextNode.prefix = node;
node.next = nextNode;
return true;
}
if (index == 0) {
beginMarker.prefix = node;
node.next = beginMarker;
beginMarker = node;
return true;
}
if (index == size) {
endMarker.next = node;
node.prefix = endMarker;
endMarker = node;
return true;
}
return false;
}
private void checkIndex(int index) {
if (index < 0 || index >= size)
throw new ArrayIndexOutOfBoundsException();
}
public boolean isEmpty() {
return size == 0;
}
public void push(T val) {
this.insertNode(size, new Node<T>(val));
size++;
}
public T pop() {
if (size == 0) {
throw new EmptyStackException();
}
T value = this.deleteEndNode();
size--;
return value;
}
public T peek() {
if (size == 0) {
throw new EmptyStackException();
}
return endMarker.value;
}
public int size() {
return size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Iterator<T> iterator = iterator();
sb.append('[');
while (iterator.hasNext()) {
sb.append(iterator.next());
sb.append(',');
}
sb.delete(sb.length() - 1, sb.length());
sb.append(']');
return sb.toString();
}
/**
* 迭代器接口
*/
@Override
public Iterator<T> iterator() {
return new LinkedListIterator();
}
private class LinkedListIterator implements java.util.Iterator<T> {
Node<T> current = beginMarker;
@Override
public boolean hasNext() {
return current != null;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
T nextItem = current.value;
current = current.next;
return nextItem;
}
@Override
public void remove() {
LinkedStack.this.pop();
}
}
}
6,HashSet
采用上述封装的MyHashMap实现HashSet,达到去重效果
package _数据结构._Set;
import _数据结构._Map.MyHashMap;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
/**
* @program: suanfa_by_java
* @author: 一树
* @data: 2020/11/16 19:50
*/
public class MyHashSet<T> implements Iterable<T> {
private final Object P = new Object();
private int size;
private MyHashMap<T, Object> map;
public MyHashSet() {
map = new MyHashMap<>();
size = 0;
}
public MyHashSet(Collection<? extends T> c) {
map = new MyHashMap<>();
size = 0;
for (T t : c) {
add(t);
}
}
public void add(T t) {
if (!map.containKey(t)) {
map.put(t, P);
size++;
}
}
public void remove(T t) {
if (map.containKey(t)) {
map.remove(t);
}
}
public int size() {
return size;
}
public boolean contain(T t) {
return map.containKey(t);
}
@Override
public Iterator<T> iterator() {
return map.enterKey().iterator();
}
}