Java实现的部分数据结构
1. Trie: 字典树
package p51;
import java.util.TreeMap;
/**
* 字典速树的实现
* @author Guozhu Zhu
* @date 2019/2/26
* @version 1.0
*
*/
public class Trie01 {
private class Node {
private boolean isWord;
public TreeMap<Character, Node> next;
public Node(boolean isWord) {
this.isWord = isWord;
next = new TreeMap<Character, Node>();
}
public Node() {
this(false);
}
}
public Node root;
public int size;
public Trie01() {
root = new Node();
this.size = 0;
}
//插入一个字符串
public void insert(String word) {
Node cur = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.next.get(c) != null) {
cur.next.put(c, new Node());
}
cur = cur.next.get(c);
}
cur.isWord = true;
}
//查找一个字符串
public boolean search(String word) {
Node cur = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (cur.next.get(c) == null) {
return false;
}
cur = cur.next.get(c);
}
return cur.isWord;
}
//查找是否是前缀
public boolean prefix(String prefix) {
Node cur = root;
for (int i = 0; i < prefix.length(); i++) {
char c = prefix.charAt(i);
if (cur.next.get(c) == null) {
return false;
}
cur = cur.next.get(c);
}
return true;
}
/* ========== Test ========== */
public static void main(String[] args) {
Trie01 trie = new Trie01();
trie.insert("zhu");
trie.insert("guo");
trie.insert("zhi");
}
}
2. Array: 动态数组
package p51;
/**
* 静态数组构造动态数组
* @author Guozhu Zhu
* @date 2019/2/27
* @version 1.0
*
*/
public class Array01<E>{
public E[] array;
public int size;
public Array01() {
this(10);
}
public Array01(int capacity) {
array = (E[]) new Object[capacity];
}
public int getSize() {
return this.size;
}
public int find(E e) {
if (e == null) {
return -1;
}
for (int i = 0; i < this.size; i++) {
if (e.equals(array[i])) {
return i;
}
}
return -1;
}
public int getCapacity() {
return this.array.length;
}
public boolean isEmpty() {
return this.size == 0;
}
public void resize(int newCapacity) {
E[] newArray = (E[]) new Object[newCapacity];
for (int i = 0; i < this.size; i++) {
newArray[i] = array[i];
}
this.array = newArray;
}
public boolean checkPositionIndex(int index) {
return index >= 0 && index <= size;
}
public boolean checkElementIndex(int index) {
return index >= 0 && index < size;
}
public E get(int index) {
if (checkElementIndex(index)) {
return this.array[index];
}
return null;
}
public E getFirst() {
if (this.size != 0) {
return get(0);
}
return null;
}
public E getLast() {
if (this.size != 0) {
return get(size-1);
}
return null;
}
public void set(int index, E e) {
if (checkElementIndex(index)) {
this.array[index] = e;
}
return;
}
public boolean contains(E e) {
if (e == null) {
return false;
}
for (int i = 0; i < this.size; i++) {
if (e.equals(this.array[i])) {
return true;
}
}
return false;
}
//add
public void add(int index, E e) {
if (checkPositionIndex(index)) {
if (this.size == this.array.length) {
resize(2*array.length);
}
for (int i = index; i < this.size; i++) {
array[i+1] = array[i];
}
array[index] = e;
size++;
} else {
throw new IllegalArgumentException("error");
}
}
public void addFirst(E e) {
add(0, e);
}
public void addLast(E e) {
add(this.size, e);
}
//remove
public E remove(int index) {
if (checkElementIndex(index)) {
E ret = array[index];
for (int i = size-1; i > index; i--) {
array[i-1] = array[i];
}
size--;
if (size <= array.length / 4 && size > 1) {
resize(array.length);
}
return ret;
} else {
throw new IllegalArgumentException("error");
}
}
public E removeFirst() {
return remove(0);
}
public E removeLast() {
return remove(this.size-1);
}
public E removeElement(E e) {
int index = find(e);
if (index == -1) {
return e;
}
return remove(index);
}
public void print() {
StringBuffer strBuf = new StringBuffer();
strBuf.append("[");
for (int i = 0; i < this.size; i++) {
strBuf.append(array[i]);
if (i == this.size-1) {
break;
}
strBuf.append(",");
}
strBuf.append("]");
System.out.println(strBuf.toString());
}
/* ========== Test ========== */
public static void main(String[] args) {
Array01<Integer> array = new Array01<>();
for (int i = 0; i < 10; i++) {
array.add(i, i);
}
array.print();
}
}
3. LinkedList: 链表的实现
package p51;
/**
* 链表的实现
* @author Guozhu Zhu
* @date 2019/2/27
* @version 1.0
*
*/
public class LinkedList01<E> {
private class Node<E>{
public E e;
public Node prev;
public Node next;
public Node(Node<E> prev, E e, Node<E> next) {
this.e = e;
this.prev = prev;
this.next = next;
}
}
public Node<E> first;
public Node<E> last;
public int size;
public int modCount;
public LinkedList01() {
}
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
//node --> index
public int indexOf(E e) {
int index = 0;
if (e == null) {
for (Node<E> x = first; x != null; x = x.next) {
index++;
if (x.e == null) {
return index;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
index++;
if (x.e.equals(e)) {
return index;
}
}
}
return -1;
}
//node --> index
public int lastIndexOf(E e) {
int index = 0;
if (e == null) {
for (Node<E> x = last; x != null; x = x.prev) {
index++;
if (x.e == null) {
return index;
}
}
} else {
for (Node<E> x = last; x != null; x = x.next) {
index++;
if (x.e.equals(e)) {
return index;
}
}
}
return -1;
}
public boolean contains(E e) {
if (indexOf(e) != -1) {
return true;
}
return false;
}
//index --> node
public Node<E> node(int index) {
if (index <= this.size/2) {
Node<E> x = first;
while (x.next != null)
x = x.next;
return x;
} else {
Node<E> x = last;
while (x.prev != null)
x = x.prev;
return x;
}
}
public void set(int index, E e) {
Node<E> x = node(index);
if (x == null) {
return;
}
x.e = e;
}
public E get(int index) {
Node<E> x = node(index);
if (x == null) {
return null;
}
return x.e;
}
public E getFirst() {
Node<E> f = first;
if (f == null) {
throw new IllegalArgumentException("error");
}
return f.e;
}
public E getLast() {
Node<E> l = last;
if (l == null) {
throw new IllegalArgumentException("error");
}
return l.e;
}
public boolean checkPositionIndex(int index) {
return index >= 0 && index <= size;
}
public boolean checkElementIndex(int index) {
return index >= 0 && index < size;
}
//add
public void add(int index, E e) {
if (checkPositionIndex(index)) {
if (index == size) {
addLast(e);
} else {
addBefore(node(index), e);
}
} else {
throw new IllegalArgumentException("error");
}
}
public void addFrist(E e) {
Node<E> f = first;
Node<E> newNode = new Node<E>(null, e, f);
first = newNode;
if (f == null) {
last = newNode;
} else {
f.prev = newNode;
}
size++;
}
public void addLast(E e) {
Node<E> l = last;
Node<E> newNode = new Node<E>(l, e, null);
last = newNode;
if (l == null) {
first = newNode;
} else {
l.next = newNode;
}
size++;
}
public void addBefore(Node<E> succ, E e) {
Node<E> pred = succ.prev;
Node<E> newNode = new Node<E>(pred, e, succ);
succ.prev = newNode;
if (pred == null) {
first = newNode;
} else {
pred.next = newNode;
}
size++;
}
//remove
public E remove(int index) {
if (checkElementIndex(index)) {
return unlink(node(index));
} else {
throw new IllegalArgumentException("error");
}
}
public E removeFirst() {
Node<E> f = first;
if (f == null) {
throw new IllegalArgumentException("error");
}
return unlinkFirst(f);
}
public E removeLast() {
Node<E> l = last;
if (l == null) {
throw new IllegalArgumentException("error");
}
return unlinkLast(l);
}
public E unlinkFirst(Node<E> x) {
E value = x.e;
Node<E> prev = x.prev;
Node<E> next = x.next;
x.e = null;
x.next = null;
first = next;
if (next == null) {
last = null;
} else {
next.prev = null;
}
return value;
}
public E unlinkLast(Node<E> x) {
E value = x.e;
Node<E> prev = x.prev;
Node<E> next = x.next;
x.e = null;
x.prev = null;
last = prev;
if (prev == null) {
first = null;
} else {
prev.next = null;
}
return value;
}
public E unlink(Node<E> x) {
E value = x.e;
Node<E> prev = x.prev;
Node<E> next = x.next;
x.e = null;
if (prev == null) {
first = null;
} else {
prev.next = next;
next.prev = null;
}
if (next == null) {
last = null;
} else {
next.prev = prev;
prev.next = null;
}
x.prev = null;
x.next = null;
size--;
return value;
}
public E removeElement(E e) {
int index = indexOf(e);
if (index == -1) {
return null;
}
return unlink(node(index));
}
public E removeElement01(E e) {
if (e == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.e == null) {
return unlink(x);
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (x.e.equals(e)) {
return unlink(x);
}
}
}
return null;
}
public void clear() {
for (Node<E> x = first; x != null; x = x.next) {
x.e = null;
}
first = null;
last = null;
size = 0;
}
public String print() {
if (this.size == 0) {
return "";
}
StringBuilder strBud = new StringBuilder();
strBud.append("[");
Node<E> x = first;
while (x != null) {
strBud.append(x.e);
x = x.next;
}
strBud.append("]");
return strBud.toString();
}
public static void main(String[] args) {
LinkedList01 list = new LinkedList01();
for (int i = 0; i < 100; i++) {
list.addLast(i);
}
System.out.println(list.getSize());
System.out.println(list.removeLast());
System.out.println(list.removeLast());
System.out.println(list.removeLast());
System.out.println(list.removeLast());
System.out.println(list.removeLast());
System.out.println(list.removeLast());
System.out.println(list.getSize());
System.out.println(list.print());
list.clear();
System.out.println(list.getSize());
}
}
4. BST:二叉搜索树的实现
package p51;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
/**
* 二叉搜索树的实现
* @author Guozhu Zhu
* @date 2019/2/26
* @version 1.0
*
*/
public class BST01<E extends Comparable<E>> {
private class Node{
public E value;
public Node left;
public Node right;
public Node(E value) {
this.value = value;
this.left = null;
this.right = null;
}
}
private Node root;
private int size;
public BST01() {
root = null;
this.size = 0;
}
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public Node getNode(Node node, E value) {
if (node == null) {
return null;
}
if (value.compareTo(node.value) > 0) {
return getNode(node.right, value);
} else if (value.compareTo(node.value) < 0) {
return getNode(node.left, value);
} else {
return node;
}
}
public boolean contains(E value) {
Node node = getNode(root, value);
if (node == null) {
return false;
}
return true;
}
//add
public void add(E value) {
root = add(root, value);
}
public Node add(Node node, E value) {
if (node == null) {
this.size++;
return new Node(value);
}
if (value.compareTo(node.value) > 0) {
node.right = add(node.right, value);
} else if (value.compareTo(node.value) < 0) {
node.left = add(node.left, value);
} else {
node.value = value;
}
return node;
}
//remove
public E remove(E value) {
Node node = getNode(root, value);
if (node == null) {
return null;
}
root = removeElement(root, value);
return value;
}
public Node removeElement(Node node, E value) {
if (node == null) {
return null;
}
if (value.compareTo(node.value) > 0) {
node.right = removeElement(node.right, value);
return node;
} else if (value.compareTo(node.value) < 0) {
node.left = removeElement(node.left, value);
return node;
} else {
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
this.size--;
return rightNode;
} else if (node.right == null) {
Node leftNode = node.left;
node.left = null;
this.size--;
return leftNode;
} else {
Node successor = minElement(node.right);
successor.right = removeMinElement(node.right);
this.size++;
successor.left = node.left;
node.left = node.right = null;
this.size--;
return successor;
}
}
}
public Node minElement(Node node) {
if (node == null) {
return null;
}
while (node.left != null) {
node = node.left;
}
return node;
}
public Node removeMinElement(Node node) {
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
this.size--;
return rightNode;
}
node.left = removeMinElement(node.left);
return node;
}
public Node maxElement(Node node) {
if (node == null) {
return node;
}
while (node.right != null) {
node = node.right;
}
return node;
}
public Node removeMaxElement(Node node) {
if (node.right == null) {
Node leftNode = node.left;
node.left = null;
this.size--;
return leftNode;
}
node.right = removeMaxElement(node.right);
return node;
}
//遍历
public void preOrder(Node node) {
if (node == null) {
return;
}
System.out.println(node.value);
preOrder(node.left);
preOrder(node.right);
}
public void inOrder(Node node) {
if (node == null) {
return;
}
inOrder(node.left);
System.out.println(node.value);
inOrder(node.right);
}
public void postOrder(Node node) {
if (node == null) {
return;
}
postOrder(node.left);
postOrder(node.right);
System.out.println(node.value);
}
public void newPreOrder() {
Stack<Node> stack = new Stack<Node>();
Node temp = root;
while (temp != null || !stack.isEmpty()) {
while (temp != null) {
System.out.println(temp.value);
stack.push(temp);
temp = temp.left;
}
if (!stack.isEmpty()) {
temp = stack.pop();
temp = temp.right;
}
}
}
public void newPostOrder() {
Stack<Node> stack = new Stack<Node>();
Node last = root;
Node temp;
stack.push(root);
while (!stack.isEmpty()) {
temp = stack.peek();
//1. p如果是叶子节点,直接输出
//2. 如果temp有孩子并且孩子都访问过,则输出temp
if ((temp.left == null && temp.right == null) || ((temp.right == null && last == temp.left) || last == temp.right)) {
System.out.println(temp.value);
last = temp;
stack.pop();
} else {
//3. 如果temp有孩子但孩子没访问过,则访问孩子
if (temp.right != null) {
stack.push(temp.right);
}
if (temp.left != null) {
stack.push(temp.left);
}
}
}
}
public ArrayList<ArrayList<E>> levelOrder() {
ArrayList<ArrayList<E>> resList = new ArrayList<ArrayList<E>>();
ArrayList<E> list = new ArrayList<E>();
Queue<Node> queue = new LinkedList<Node>();
queue.offer(root);
int cur = 1;
int next = 0;
while (!queue.isEmpty()) {
Node curNode = queue.poll();
list.add(curNode.value);
cur--;
if (curNode.left != null) {
queue.offer(curNode.left);
next++;
}
if (curNode.right != null) {
queue.offer(curNode.right);
next++;
}
if (cur == 0) {
cur = next;
next = 0;
resList.add(list);
list = new ArrayList<E>();
}
}
return resList;
}
/* =========== Test =========== */
public static void main(String[] args) {
BST01<Integer> bst = new BST01<>();
bst.add(0);
bst.add(1);
bst.add(5);
bst.add(3);
bst.add(2);
bst.add(4);
//bst.inOrder(bst.root); //0, 1, 2, 3, 4, 5
//bst.preOrder(bst.root); //0, 1, 5, 3, 2, 4
//bst.postOrder(bst.root); //2, 4, 3, 5, 1, 0
bst.newPostOrder();
/*ArrayList<ArrayList<Integer>> list = bst.levelOrder(); //0, 1, 5, 3, 2, 4
for (ArrayList<Integer> l : list) {
for (Integer i : l) {
System.out.print(i);
}
System.out.println();
}*/
//bst.newPreOrder();
//bst.newInOrder();
}
}
5. BSTMap: 基于BST实现的Map
package p51;
/**
* 基于BST实现的Map
* @author Guozhu Zhu
* @date 2019/2/26
* @version 1.0
*
*/
public class BSTMap01<K extends Comparable <K>, V> {
private class BST<K extends Comparable <K>, V> {
private class Node {
public K key;
public V value;
public Node left;
public Node right;
public Node(K key, V value) {
this.key = key;
this.value = value;
this.left = null;
this.right = null;
}
}
private Node root;
private int size;
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public Node getNode(Node node, K key) {
if (node == null) {
return null;
}
if (key.compareTo(node.key) > 0) {
return getNode(node.right, key);
} else if (key.compareTo(node.key) < 0) {
return getNode(node.left, key);
} else {
return node;
}
}
public boolean contains(K key) {
Node node = getNode(root, key);
if (node == null) {
return false;
}
return true;
}
//add
public void add(K key, V value) {
root = add(root, key, value);
}
private Node add(Node node, K key, V value) {
if (node == null) {
this.size++;
return new Node(key, value);
}
if (key.compareTo(node.key) > 0) {
node.right = add(node.right, key, value);
} else if (key.compareTo(node.key) < 0) {
node.left = add(node.left, key, value);
} else {
node.value = value;
}
return node;
}
//remove
public V remove(K key) {
Node node = getNode(root, key);
if (node == null) {
return null;
}
root = removeElement(root, key);
return node.value;
}
private Node removeElement(Node node, K key) {
if (node == null) {
return null;
}
if (key.compareTo(node.key) > 0) {
node.right = removeElement(node.right, key);
} else if (key.compareTo(node.key) < 0) {
node.left = removeElement(node.left, key);
} else {
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
size--;
return rightNode;
} else if (node.right == null) {
Node leftNode = node.left;
node.left = null;
size--;
return leftNode;
} else {
Node successor = minElement(node.right);
successor.right = removeMinElement(node.right);
size++;
successor.left = node.left;
node.left = node.right = null;
size--;
return successor;
}
}
return node;
}
public Node minElement(Node node) {
if (node == null) {
return null;
}
while (node.left != null) {
node = node.left;
}
return node;
}
public Node removeMinElement(Node node) {
if (node.left == null) {
Node rightNode = node.right;
node.right = null;
size--;
return rightNode;
}
node.left = removeMinElement(node.left);
return node;
}
public V get(K key) {
Node node = getNode(root, key);
if (node == null) {
return null;
}
return node.value;
}
public void set(K key, V value) {
Node node = getNode(root, key);
if (node == null) {
return;
}
node.value = value;
}
}
public BST<K, V> bst;
public int size;
public BSTMap01() {
bst = new BST<K, V>();
}
public void add(K key, V value) {
bst.add(key, value);
}
public boolean isEmpty() {
return bst.isEmpty();
}
public boolean contains(K key) {
return bst.contains(key);
}
public int getSize() {
return bst.getSize();
}
public V remove(K key) {
return bst.remove(key);
}
public void set(K key, V value) {
bst.set(key, value);
}
public V get(K key) {
return bst.get(key);
}
/* ========== Test ========== */
public static void main(String[] args) {
BSTMap01<Integer, Integer> bstmap = new BSTMap01<>();
for (int i = 0; i < 10; i++) {
bstmap.add(i, i);
}
System.out.println(bstmap.getSize());
//System.out.println(bstmap.get(9));
int ans = bstmap.remove(1);
System.out.println(ans);
//System.out.println(bstmap.get(1));
//System.out.println(bstmap.get(0));
System.out.println(bstmap.getSize());
}
}
6. BSTSet: 基于BSTMap实现的Set
package p51;
/**
* BSTSet
* @author Guozhu Zhu
* @date 2019/2/27
* @version 1.0
*
*/
public class BSTSet01<E extends Comparable<E>> {
public BSTMap01<E, Object> bstMap;
public Object obj = new Object();
public BSTSet01() {
bstMap = new BSTMap01<>();
}
public void add(E e) {
bstMap.add(e, obj);
}
public int getSize() {
return bstMap.getSize();
}
public boolean isEmpty() {
return bstMap.isEmpty();
}
public boolean contains(E e) {
return bstMap.contains(e);
}
public void remove(E e) {
bstMap.remove(e);
}
}
7. HashTable的实现
package p51;
/**
* HashTable的实现
* @author Guozhu Zhu
* @date 2019/3/2
* @version 1.0
* 哈希表是一种典型的空间换时间的策略,其查找速度为O(1)时间复杂度
* 但是空间使用却是O(n), 在java集合库HashMap / HashSet都是采用链地址法来实现的
* HashTable的基本原理就是采用M个数组做桶,桶中每一个元素就是一个单链表。
* 当元素的hashcode被散射到各个桶中,散射的过程就是取余;
* 一般情况下,取余采用素数,这样有利于将hashcode均匀打散,这是有数学依据的
* 此外,可以参考java集合框架中那样,设置加载因子,当达到一定程度就扩容。
*
*
*/
public class HashTable01<K, V> {
private class Entry<K, V> {
private 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(K key, V value) {
this(key, value, null);
}
public Node() {
this(null, null, null);
}
public String toString() {
return key.toString() + "," +
value.toString();
}
}
private Node head; //链表头结点
private int size;
public Entry() {
head = null;
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public void add(K key, V value) {
if (head == null) {
head = new Node(key, value, null);
} else {
Node prev = head;
for (int i = 0; i < size-1; i++) {
if (prev.key.equals(key)) {
prev.value = value;
return;
}
prev = prev.next;
}
if (prev.key.equals(key)) {
prev.value = value;
return;
}
prev.next = new Node(key, value);
}
size++;
}
public V get(K key) {
if (key == null) {
throw new NullPointerException("key is null");
}
Node cur = head;
for (int i = 0; i < size; i++) {
if (cur.key.equals(key)) {
return cur.value;
}
cur = cur.next;
}
return null;
}
public boolean contains(K key) {
if (head == null) {
return false;
}
Node cur = head;
while (cur != null) {
if (cur.key.equals(key)) {
return true;
}
cur = cur.next;
}
return false;
}
//存在bug
public void removeElement(K key) {
if (head == null) {
return;
}
//删除链表其他节点
Node prev = head;
while (prev.next != null) {
if (prev.next.key.equals(key)) {
break;
}
prev = prev.next;
}
if (prev.next != null) {
Node delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;
size--;
}
}
}
Entry<K, V> hashtable[];
private int M;
private int size;
public HashTable01(int M) {
this.M = M;
size = 0;
hashtable = new Entry[M];
for (int i = 0; i < M; i++) {
hashtable[i] = new Entry();
}
}
public HashTable01() {
this(11);
}
public int hash(K key) {
return (key.hashCode()&0x7fffffff) % M;
}
public void add(K key, V value) {
Entry entry = hashtable[hash(key)];
if (entry.contains(key)) {
entry.add(key, value);
} else {
entry.add(key, value);
size++;
}
}
public void remove(K key) {
Entry entry = hashtable[hash(key)];
if (entry.contains(key)) {
entry.removeElement(key);
size--;
}
}
public boolean contains(K key) {
Entry entry = hashtable[hash(key)];
if (entry.contains(key)) {
return true;
}
return false;
}
public V get(K key) {
return hashtable[hash(key)].get(key);
}
/* =========== Test ========== */
public static void main(String[] args) {
HashTable01 hashtable = new HashTable01();
hashtable.add(1, 2);
hashtable.remove(1);
System.out.println(hashtable.get(1));
}
}
8. HashMap的实现
package p51;
import java.util.TreeMap;
/**
* 在java集合框架1.7版本以前,HashTable与HashMap的实现原理差别不大。都是基于数组作为哈希桶,然后每个桶下面挂个链表。
* 在java的1.8版本中,HashMap采用了红黑树。在之前版本中使用的链表。阅读源码的知道,HashMap进行了优化,当每个桶下面的元素小于8,还是采用链表。当大于8的时候
* 将链表转化为红黑树来提高检索效率。这些都是优化手段
* @author Guozhu Zhu
* @date 2019/1/2
* @version 1.0
*
*/
public class HashMap01<K, V> {
private static final int Default_Capacity = 16;
private static final float Default_load_factor = 0.75f;
private float load_factor;
private TreeMap<K, V>[] hashMap;
private int size;
private int M;
public HashMap01() {
this(Default_Capacity);
}
public HashMap01(int M) {
this(M, Default_load_factor);
}
public HashMap01(int M, float load_factor) {
this.M = M;
this.load_factor = load_factor;
size = 0;
hashMap = new TreeMap[M];
for (int i = 0; i < M; i++) {
hashMap[i] = new TreeMap<K, V>();
}
}
private int hash(K key) {
return (key.hashCode()&0x7fffffff) % M;
}
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public void add(K key, V value) {
TreeMap<K, V> map = hashMap[hash(key)];
if (map.containsKey(key)) {
map.put(key, value);
} else {
map.put(key, value);
size++;
if (size >= load_factor * M) {
resize(2*M); //扩容
}
}
}
public V remove(K key) {
V ret = null;
TreeMap<K, V> map = hashMap[hash(key)];
if (map.containsKey(key)) {
ret = map.remove(key);
size--;
}
return ret;
}
public void set(K key, V value) {
hashMap[hash(key)].put(key, value);
}
public boolean contains(K key) {
return hashMap[hash(key)].containsKey(key);
}
public V get(K key) {
return hashMap[hash(key)].get(key);
}
private void resize(int newM) {
TreeMap<K, V>[] newHashMap = new TreeMap[newM];
for (int i = 0; i < newM; i++) {
newHashMap[i] = new TreeMap<K, V>();
}
int oldM = M;
this.M = M;
for (int i = 0; i < oldM; i++) {
TreeMap<K, V> map = hashMap[i];
for (K key : map.keySet()) {
newHashMap[hash(key)].put(key, map.get(key));
}
}
this.hashMap = newHashMap;
}
}
9. PriorityQueue: 优先级队列的实现
package p51;
/**
* 优先级队列实现
* @author Guozhu Zhu
* @date 2019/2/28
* @version 1.0
*
*/
public class PriorityQueue01 {
public int[] array;
public int size;
public PriorityQueue01() {
array = new int[32];
}
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public void resize(int newCapacity) {
int[] newArray = new int[newCapacity];
for (int i = 0; i < size; i++) {
newArray[i] = array[i];
}
this.array = newArray;
}
//offer
public void offer(int e) {
if (this.size == this.array.length) {
resize(this.array.length*2);
}
this.array[size] = e;
upAdjust();
size++;
}
public int poll() {
if (this.size == 0) {
throw new IllegalArgumentException("error");
}
int ret = array[0];
array[0] = array[this.size-1];
downAdjust();
size--;
return ret;
}
public void upAdjust() {
int childIndex = size;
int temp = array[childIndex];
int parentIndex = childIndex / 2;
while (childIndex > 0 && temp > array[parentIndex]) {
array[childIndex] = array[parentIndex];
childIndex = parentIndex;
parentIndex = parentIndex / 2;
}
array[childIndex] = temp;
}
public void downAdjust() {
int parentIndex = 0;
int temp = this.array[parentIndex];
int childIndex = parentIndex*2+1;
while (childIndex < size) {
while (childIndex+1 < size && array[childIndex+1] > array[childIndex]) {
childIndex++;
}
if (temp > array[childIndex]) {
break;
}
array[parentIndex] = array[childIndex];
parentIndex = childIndex;
childIndex = childIndex*2+1;
}
array[parentIndex] = temp;
}
public static void main(String[] args) {
PriorityQueue01 queue = new PriorityQueue01();
for (int i = 0; i < 1000; i++) {
queue.offer(i);
}
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
}
}
10. AVLTree: 平衡树的实现
package p51;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
/**
* AVL树的实现
* @author Guozhu Zhu
* @date 2019/2/27
* @version 1.0
*
*/
public class AVLTree01<K extends Comparable<K>, V> {
public class Node {
public K key;
public V value;
public Node left;
public Node right;
public int height;
public Node(K key, V value) {
this.key = key;
this.value = value;
this.left = null;
this.right = null;
this.height = 0;
}
}
private Node root;
private int size;
public AVLTree01() {
root = null;
size = 0;
}
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public int getHeight(Node node) {
if (node == null) {
return -1;
}
return node.height;
}
public boolean isBalanced() {
return isBalanced(root);
}
private boolean isBalanced(Node node) {
if (node == null) {
return true;
}
int balanceFactor = getBalanceFactor(node);
if (Math.abs(balanceFactor) > 1) {
return false;
}
return isBalanced(node.left) && isBalanced(node.right);
}
public int getBalanceFactor(Node node) {
if (node == null) {
return 0;
}
return getHeight(node.left) - getHeight(node.right);
}
public void add(K key, V value) {
root = add(root, key, value);
}
/**private Node leftRotate(Node node) {
//System.out.println(node);
Node x = node.right;
node.right = x.left;
x.left = node;
x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
return x;
}*/
/*
private Node leftRotate(Node node) {
Node x = node.right;
//Node T3 = x.left;
node.right = x.left;
x.left = node;
//node.right = T3;
node.height = Math.max(getHeight(node.left), getHeight(node.right))+1;
x.height = Math.max(getHeight(x.left), getHeight(x.right))+1;
return x;
}*/
//左旋
private Node leftRotate(Node node) {
Node x = node.right;
node.right = x.left;
x.left = node;
node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
return x;
}
private Node rightRotate(Node node) {
Node x = node.left;
node.left = x.right;
x.right = node;
node.height = Math.max(getHeight(node.left), getHeight(node.right))+1;
x.height = Math.max(getHeight(x.left), getHeight(x.right)) + 1;
return x;
}
/**private Node add(Node node, K key, V value) {
if (node == null) {
size++;
return new Node(key, value);
}
if (key.compareTo(node.key) > 0) {
node.right = add(node.right, key, value);
} else if (key.compareTo(node.key) < 0) {
node.left = add(node.left, key, value);
} else {
node.value = value;
}
node.height = Math.max(getHeight(node.left), getHeight(node.right)) +1;
int balanceFactor = getBalanceFactor(node);
if (balanceFactor > 1 && getBalanceFactor(node.left) >= 0) {
return rightRotate(node);
} else if (balanceFactor > 1 && getBalanceFactor(node.left) < 0) {
node.right = rightRotate(node.right);
return leftRotate(node);
} else if (balanceFactor < -1 && getBalanceFactor(node.right) <= 0) {
return leftRotate(node);
} else if (balanceFactor < -1 && getBalanceFactor(node.right) > 0) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
return node;
}*/
public Node add(Node node, K key, V value) {
if (node == null) {
size++;
return new Node(key, value);
}
if (key.compareTo(node.key) > 0) {
node.right = add(node.right, key, value);
} else if (key.compareTo(node.key) < 0) {
node.left = add(node.left, key, value);
} else {
node.value = node.value;
}
node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
int balanceFactor = getBalanceFactor(node);
if (balanceFactor > 1 && getBalanceFactor(node.left) >= 0) {
return rightRotate(node);
} else if (balanceFactor > 1 && getBalanceFactor(node.left) < 0) {
node.right = rightRotate(node.right);
return leftRotate(node.right);
} else if (balanceFactor < -1 && getBalanceFactor(node.right) <= 0) {
return leftRotate(node);
} else if (balanceFactor < -1 && getBalanceFactor(node.right) > 0) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
return node;
}
private ArrayList<ArrayList<V>> levelOrder() {
Queue<Node> queue = new LinkedList<Node>();
ArrayList<V> list = new ArrayList<V>();
ArrayList<ArrayList<V>> resList = new ArrayList<ArrayList<V>>();
queue.offer(root);
int cur = 1;
int next = 0;
while (!queue.isEmpty()) {
Node curNode = queue.poll();
//System.out.println(curNode.value);
list.add(curNode.value);
cur--;
if (curNode.left != null) {
queue.offer(curNode.left);
next++;
}
if (curNode.right != null) {
queue.offer(curNode.right);
next++;
}
if (cur == 0) {
resList.add(list);
cur = next;
next = 0;
list = new ArrayList<V>();
}
}
return resList;
}
public static void main(String[] args) {
AVLTree01<Integer, Integer> avlTree = new AVLTree01<Integer, Integer>();
for (int i = 0; i < 29; i++) {
avlTree.add(i, i);
}
//avlTree.inOrder();
ArrayList<ArrayList<Integer>> resList = avlTree.levelOrder();
for (ArrayList<Integer> l : resList) {
for (Integer e : l) {
System.out.print(e);
}
System.out.println();
}
System.out.println(avlTree.getSize());
/*AVLTree01<Integer, Integer> avl = new AVLTree01<Integer, Integer>();
for (int i = 0; i < 10; i++) {
avl.add(i, i);
}
ArrayList<ArrayList<Integer>> res = avl.levelOrder();
for (ArrayList<Integer> l : res) {
for (Integer i : l) {
System.out.print(i);
}
System.out.println();
}*/
}
}
11. RBTree: 红黑树的实现
package p51;
/**
* 红黑树
* 1. 节点为红或黑
* 2. 根节点为黑
* 3. 孩子节点为nil的黑色节点
* 4. 若该节点为红节点,则子节点都是黑色
* 5. 任意节点到其叶子节点的路径上包含的黑色节点个数相同
* @author Guozhu
* @date 2019/2/27
* @version 1.0
*
*/
public class RBTree01<K extends Comparable<K>, V>{
public class Node {
public K key;
public V value;
public Node left;
public Node right;
public boolean color;
public Node(K key, V value) {
this.key = key;
this.value = value;
this.left = left;
this.right = right;
this.color = RED;
}
}
public static final boolean RED = true;
public static final boolean BLACK = false;
public Node root;
public int size;
public RBTree01() {
root = null;
size = 0;
}
/**
* 左旋: 左黑右红
*/
public Node leftRotate(Node node) {
Node x = node.right;
node.right = x.left;
x.left = node;
x.color = node.color;
node.color = RED;
return x;
}
/**
* 右旋:左红左子红
*/
public Node rightRotate(Node node) {
Node x = node.left;
node.left = x.right;
x.right = node;
x.color = node.color;
node.color = RED;
return x;
}
public void flipColors(Node node) {
node.color = RED;
node.left.color = BLACK;
node.right.color = BLACK;
}
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public void add(K key, V value) {
root = add(root, key, value);
}
public boolean isRed(Node node) {
if (node == null) {
return RED;
}
return node.color;
}
public Node add(Node node, K key, V value) {
if (node == null) {
size++;
return new Node(key, value);
}
if (key.compareTo(node.key) > 0) {
node.right = add(node.right, key, value);
} else if (key.compareTo(node.key) < 0) {
node.left = add(node.left, key, value);
} else {
node.value = node.value;
}
if (isRed(node.right) && !isRed(node.left)) {
leftRotate(node);
} else if (isRed(node.left) && isRed(node.left.left)) {
rightRotate(node);
} else if (isRed(node.left) && isRed(node.right)) {
flipColors(node);
}
return node;
}
public Node getNode(Node node, K key) {
if (node == null) {
return null;
}
if (key.compareTo(node.key) > 0) {
return getNode(node.right, key);
} else if (key.compareTo(node.key) < 0) {
return getNode(node.left, key);
} else {
return node;
}
}
public V get(K key) {
Node node = getNode(root, key);
if (node == null) {
return null;
}
return node.value;
}
public void set(K key, V value) {
Node node = getNode(root, key);
if (node == null) {
return;
}
node.value = value;
}
public boolean contains(K key) {
Node node = getNode(root, key);
if (node == null) {
return false;
}
return true;
}
}
12. Search: 查找算法
package p51;
/**
* 顺序表的查找
* @author Guozhu Zhu
* @date 2019/2/27
* @version 1.0
*
*/
public class SearchDemo01 {
/* ========== Test ========== */
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
//int ans = search02(arr, 6, 0, 10);
int ans = search03(arr, 6);
System.out.println(ans); //ans = 5
}
//O(n)
public static int search01(int[] arr, int target) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
return i;
}
}
return -1;
}
//O(lgn)
public static int search02(int[] arr, int target, int low, int high) {
if (low > high) {
return -1;
}
int mid = (low+high) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) {
return search02(arr, target, low, mid-1);
} else if (arr[mid] < target) {
return search02(arr, target, mid+1, high);
}
return -1;
}
//O(lgn)
public static int search03(int[] arr, int target) {
int low = 0;
int high = arr.length-1;
int mid = 0;
while (low <= high) {
mid = (low+high) / 2;
if (arr[mid] > target) {
high = mid-1;
} else if (arr[mid] < target) {
low = mid+1;
} else {
return mid;
}
}
return -1;
}
}
13. Sort: 排序的实现
package p51;
/**
* 排序算法实现
* @author Guozhu Zhu
* @date 2019/2/27
* @version 1.0
*
*/
public class SortDemo01 {
/* ========== Test ========== */
public static void main(String[] args) {
int[] arr = {1, 3, 2, 4, 6, 5};
//sort01(arr);
//sort02(arr);
//sort03(arr);
//sort04(arr);
//sort05(arr);
//sort06(arr, 0, arr.length-1);
//sort06(arr, 0, arr.length-1);
//sort07(arr);
sort08(arr);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
//冒泡排序算法实现
public static void sort01(int[] arr) {
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if (arr[j+1] < arr[j]) {
int temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
}
//选择排序算法实现
public static void sort02(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
}
//插入排序算法实现
public static void sort03(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int temp = arr[i];
int j = i-1;
while (j >= 0 && temp < arr[j]) {
arr[j+1] = arr[j];
j = j-1;
}
arr[j+1] = temp;
}
}
//二分插入排序算法实现
public static void sort04(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int temp = arr[i];
int low = 0;
int high = i-1;
int mid = 0;
while (low <= high) {
mid = (low+high) / 2;
if (arr[mid] > temp) {
high = mid-1;
} else {
low = mid+1;
}
}
for (int j = i-1; j >= low; j--) {
arr[j+1] = arr[j];
}
arr[low] = temp;
}
}
//希尔排序算法实现
public static void sort05(int[] arr) {
int gap = arr.length / 2;
while (gap >= 1) {
for (int i = gap; i < arr.length; i++) {
int temp = arr[i];
int j = i-gap;
while (j >= 0 && temp < arr[j]) {
arr[j+gap] = arr[j];
j = j-gap;
}
arr[j+gap] = temp;
}
gap = gap / 2;
}
}
//快速排序算法实现
public static void sort06(int[] arr, int left, int right) {
if (left > right) {
return;
}
int i = left;
int j = right;
int k = arr[i];
while (i < j) {
while (i < j && k <= arr[j]) {
j--;
}
arr[i] = arr[j];
while (i < j && k >= arr[i]) {
i++;
}
}
arr[i] = k;
sort06(arr, left, i-1);
sort06(arr, i+1, right);
}
//归并排序算法实现
public static void sort07(int[] arr) {
int[] temp = new int[arr.length];
MergeSort(arr, 0, arr.length-1, temp);
}
public static void MergeSort(int[] arr, int first, int last, int[] temp) {
if (first < last) {
int mid = (first+last) / 2;
MergeSort(arr, first, mid, temp);
MergeSort(arr, mid+1, last, temp);
MergeCore(arr, first, mid, last, temp);
}
}
public static void MergeCore(int[] arr, int first, int mid, int last, int[] temp) {
int i = first;
int j = mid+1;
int m = mid;
int n = last;
int k = 0;
while (i <= m && j <= n) {
if (arr[i] < arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
while (i <= m) {
temp[k++] = arr[i++];
}
while (j <= n) {
temp[k++] = arr[j++];
}
for (int a = 0; a < k; a++) {
arr[a+first] = temp[a];
}
}
public static void sort08(int[] arr) {
int len = arr.length;
for (int i = (len-1) / 2; i >= 0; i--) {
downAdjust(arr, i, arr.length-1);
}
for (int i = arr.length-1; i > 0; i--) {
swap(arr, 0, i);
downAdjust(arr, 0, i-1);
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void downAdjust(int[] arr, int parentIndex, int length) {
int childIndex = parentIndex*2+1;
int temp = arr[parentIndex];
while (childIndex <= length) {
if (childIndex+1 <= length && arr[childIndex+1] > arr[childIndex]) {
childIndex++;
}
if (temp > arr[childIndex]) {
break;
}
arr[parentIndex] = arr[childIndex];
parentIndex = childIndex;
childIndex = childIndex*2+1;
}
arr[parentIndex] = temp;
}
}
14. String: 字符串的模式匹配算法
package p51;
/**
* 字符串的模式匹配算法实现
* @author Guozhu Zhu
* @date 2019/3/1
* @version 1.0
*
*/
public class StringTest {
/* ========== Test ========== */
public static void main(String[] args) {
String S = "zhuguozhu";
String T = "ozh";
int[] next = getNext(T);
//int ans = BF(S, T);
int ans = kmp(S, T, next);
System.out.println(ans);
}
public static int BF(String S, String T) {
char[] SArray = S.toCharArray();
char[] TArray = T.toCharArray();
int i = 0;
int j = 0;
while (i < SArray.length && j < TArray.length) {
if (SArray[i] == TArray[j]) {
i++;
j++;
} else {
i = i-(j-1);
j = 0;
}
}
if (j >= TArray.length) {
return i-TArray.length;
}
return -1;
}
public static int[] getNext(String T) {
char[] TArray = T.toCharArray();
int j = 0;
int k = -1;
int[] next = new int[T.length()];
next[0] = -1;
while (j < T.length()-1) {
if (k == -1 || TArray[j] == TArray[k]) {
k++;
j++;
if (TArray[j] != TArray[k]) {
next[j] = k;
} else {
next[j] = next[k];
}
} else {
k = next[k];
}
}
return next;
}
public static int kmp(String S, String T, int[] next) {
char[] SArray = S.toCharArray();
char[] TArray = T.toCharArray();
int i = 0;
int j = 0;
while (i < S.length() && j < T.length()) {
if (j == -1 || SArray[i] == TArray[j]) {
i++;
j++;
} else {
j = next[j];
}
}
if (j >= TArray.length) {
return i-TArray.length;
}
return -1;
}
}
补充01:(带虚拟头结点的单链表)
public class SingleLinkedList01<E> {
private class Node<E> {
public E e;
public Node<E> next;
public Node(E e, Node<E> next) {
this.e = e;
this.next;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return e.toString();
}
}
private Node dummyHead;
private int size = 0;
public SingleLinkedList01() {
dummyHead = new Node();
size = 0;
}
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public boolean checkPositionIndex(int index) {
return (index >= 0 && index <= this.size);
}
public boolean checkElementIndex(int index) {
return (index >= 0 && index <= this.size);
}
public void add(int index, E e) {
if (checkPositionIndex(index)) {
Node prev = dummyHead;
for (int i = 0; i < index; i++) {
prev = prev.next;
}
Node<E> newNode = new Node<E>();
newNode.next = prev.next;
prev.next = newNode;
size++;
} else {
throw new IllegalArgumentException("error");
}
}
public void addFirst(E e) {
add(0, e);
}
public void addLast(E e) {
add(size, e);
}
public E get(int index) {
if (checkElementIndex(index)) {
Node cur = dummyHead.next;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.e;
} else {
throw new IllegalArgumentException("error");
}
}
public E getFirst() {
return get(0);
}
public E getLast() {
return get(this.size-1);
}
public E set(int index, E e) {
if (checkElementIndex(index)) {
Node<E> cur = dummyHead.next;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
E ret = cur.e;
cur.e = e;
return ret;
} else {
throw new IllegalArgumentException("error");
}
}
public boolean contains(E e) {
Node<E> cur = dummyHead.next;
while (cur != null) {
if (cur.e.equals(e)) {
return true;
}
cur = cur.next;
}
return false;
}
public E remove(int index) {
if (checkPositionIndex(index)) {
Node<E> prev = dummyHead;
for (int i = 0; i < index; i++) {
prev = prev.next;
}
Node<E> retNode = prev.next;
prev.next = retNode.next;
retNode.next = null;
size--;
return retNode.e;
} else {
throw new IlleaglArgumentException("error");
}
}
public E removeFirst() {
return remove(0);
}
public E removeLast() {
return remove(this.size-1);
}
public void removeElement(E e) {
Node<E> prev = dummyHead;
while (prev.next != null) {
if (prev.next.e.equals(e)) {
break;
}
prev = prev.next;
}
if (prev.next != null) {
Node<E> retNode = prev.next;
prev.next = retNode.next;
retNode.next = null;
size--;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
Node<E> cur = dummyHead.next;
while (cur != null) {
sb.append(cur.e + "->");
cur = cur.next;
}
sb.append("NULL");
return sb.toString();
}
}
补充02(不带虚拟头结点的单链表)
class SingleLinkedList02<E> {
private class Node<E> {
E e;
Node<E> next;
public Node(E e, Node<E> next) {
this.e = e;
this.next = next;
}
public Node(E e) {
this.e = e;
}
public Node() {
this(null, null);
}
public String toString() {
return e.toString();
}
}
public Node<E> head;
public int size = 0;
public SingleLinkedList() {
this.head = null;
this.size = 0;
}
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public void addFirst(E e) {
head = new Node(e, head);
size++;
}
public boolean checkPositionIndex(int index) {
return (index >= 0 && index <= this.size);
}
public boolean checkElementIndex(int index) {
return (index >= 0 && index < this.size);
}
public void add(int index, E e) {
if (checkPositionIndex(index)) {
if (index == 0) {
addFirst(e);
} else {
Node<E> prev = head;
for (int i = 0; i < index-1; i++) {
prev = prev.next;
}
prev.next = new Node(e, prev.next); //先连后断
size++;
}
} else {
throw new IllegalArgumentException("error");
}
}
public void addLast(E e) {
add(this.size, e);
}
public E get(int index) {
if (!checkElementIndex(index)) {
throw new IllegalArgumentException("error");
}
Node<E> cur = head;
for (int i = 0; i < index; i++) {
cur = cur.next;
}
return cur.e;
}
public E getFirst() {
return get(0);
}
public E getLast() {
return get(this.size-1);
}
public boolean contains(E e) {
Node<E> cur = head;
while (cur != null) {
if (cur.e.equals(e)) {
return true;
}
}
return false;
}
public void remove(int index) {
if (checkElementIndex(index)) {
Node<E> prev = head;
for (int i = 0; i < index-1; i++) {
prev = prev.next;
}
if (prev.next != null) {
Node<E> delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;
size--;
}
} else {
throw new IllegalArgumentException("error");
}
}
public void removeFirst() {
remove(0);
}
public void removeLast() {
remove(this.size-1);
}
public void removeElement(E e) {
Node<E> cur = head;
while (cur.next != null) {
if (cur.next.e.equals(e)) {
break;
}
cur = cur.next;
}
if (cur.next != null) {
Node<E> delNode = cur.next;
cur.next = delNode.next;
delNode.next = null;
size--;
}
}
public static void main(String[] args) {
SingleLinkedList<Integer> list = new SingleLinkedList<Integer>();
for (int i = 0; i < 10; i++) {
list.add(i, i);
}
System.out.println(list.get(0));
System.out.println(list.get(8));
System.out.println(list.get(6));
}
}
补充03(跳跃表)
package week8first;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 跳跃表的基本实现(基于链表)
* @author Guozhu Zhu
* @date 2020/4/26
* @version 1.0
*
*/
public class SkipList<K extends Comparable<K>, V>{
// head节点不存储实际数据,表示层级
private Node head;
// 构建随机数对象
private Random random;
private long size;
// 采用抛硬币的概率 = 0.5
private double p;
private class Node {
public K key; //数据的key
public V value;
public long level;
public Node next;
public Node down;
public Node (K key, V value, long level, Node next, Node down) {
this.key = key;
this.value = value;
this.level = level;
this.down = down;
}
}
public SkipList01() {
head = new Node(null, null, 0, null, null);
random = new Random();
size = 0;
p = 0.5;
}
/**
* 抛硬币策略决定新添加的数据,在第几层之下构建索引节点
* 利用0-1之间的随机数是否小于0.5作为概率事件,如果大于0.5直接返回,
* 否则就一直抛,直到出现大于0.5概率事件,在不断抛的过程,使用level计数
* level最大受限于当前的节点个数
*/
private long level() {
long level = 0;
double randomNumber = random.nextDouble();
while (level <= size && randomNumber < p) {
level++;
randomNumber = random.nextDouble();
}
return level;
}
public void add(K key, V value) {
// 抛硬币决定当前节点要构建的索引节点的层级
long level = level();
// 如果新构建的level大于原head的层级,需要使用新的层级作为head
// 旧的head, 作为新的down节点
if (level > head.level) {
head = new Node(null, null, level, null, head);
}
Node current = head;
Node last = null;
while (current != null) {
// 判断,下一个节点的key是否大于当前要插入的key
if (current.next == null || current.next.key.compareTo(key) > 0) {
// 在大于的情况下判断新节点的层级是否大于当前对比的层级
if (level >= current.level) {
Node newNode = new Node(key, value, current.level, current.next, null);
if (last != null) {
last.down = newNode;
}
// 追加当前节点
current.next = newNode;
last = newNode;
}
// 下降一级更新
current = current.down;
continue;
} else if (current.next.key.equals(key)) {
// 如果是等于,就是更新值,然后返回
current.next.value = value;
return;
}
// 到这一步,就说明新插入的值大于当前节点,那就继续向后遍历查询
current = current.next;
}
// 每新增一个节点,数量就加一
size++;
}
public V search(K key) {
Node current = head;
while (current != null) {
// 如果next的值大于当前要查询的值,说明当前的值在左边,然后就下降,继续查找
if (current.next == null || current.next.key.compareTo(key) > 0) {
current = current.down;
continue;
} else if (current.next.key.equals(key)) {
return current.next.value;
}
// 继续向后搜索
current = current.next;
}
return null;
}
public V remove(K key) {
V value = null;
Node current = head;
while (current != null) {
// 判断是否在左边
if (current.next == null || current.next.key.compareTo(key) >= 0) {
// 是的情况下, 判断是否相等
if (current.next != null && current.next.key.equals(key)) {
// 如果相等,就获取值
value = current.next.value;
// 然后就将引用覆盖掉
current.next = current.next.next;
size--;
}
// 下沉继续处理
current = current.down;
continue;
}
// 继续向右查询
current = current.next;
}
return value;
}
public boolean containsKey(K key) {
return search(key) != null;
}
// 统计当前跳跃表的节点个数,就可以使用size属性代替
public long size() {
Node current = head;
long count = 0;
// head 不为 null
if (current != null) {
// 一直下沉到最下面的一级
while (current.down != null) {
current = current.down;
}
// 从左向右遍历统计
while (current.next != null) {
count++;
current = current.next;
}
}
return count;
}
// 查询最小值
public V findMin() {
Node current = head;
if (current == null) {
return null;
}
// 下沉下去,最底层链表的第一个值
while (current.down != null) {
current = current.down;
}
return current.next.value;
}
// 查询最大值
public V findMax() {
Node current = head;
if (current == null) {
return null;
}
while (current.next.next != null) {
current = current.next;
}
while (current.down != null) {
current = current.down;
}
while (current.next.next != null) {
current = current.next;
}
return current.next.value;
}
// 范围检索
public List<V> findRange(K start, K end) {
List<V> list = new ArrayList<V>();
Node current = head;
while (current != null) {
// 如果next的值大于当前要查询的值,就说明当前的值在左边,然后就下降,继续查找
if (current.next != null || current.next.key.compareTo(start) > 0) {
current = current.down;
continue;
} else if (current.next.key.equals(start)) {
Node temp = current.next;
// 搜索范围
while (temp != null && temp.key.compareTo(end) <= 0) {
list.add(temp.value);
temp = temp.next;
}
return list;
}
// 继续向后搜索
current = current.next;
}
return list;
}
/* ========== Test ========== */
public static void main(String[] args) {
SkipList<Integer, String> skipList = new SkipList<Integer, String>();
skipList.add(3, "3");
skipList.add(1, "1");
skipList.add(11, "11");
skipList.add(16, "16");
skipList.add(4, "4");
skipList.add(2, "2");
skipList.add(8, "8");
System.out.println(skipList.size());
System.out.println(skipList.findMax());
System.out.println(skipList.findMin());
System.out.println(skipList.findRange(3, 11));
}
}