Java实现的部分数据结构

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));	
	}

}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值