Map接口
public interface Map<K,V> {
void add(K key, V value);
V remove(K key);
boolean contains(K key);
V get(K key);
void set(K key, V newValue);
int getSize();
boolean isEmpty();
}
实现类
/**
* @author panghu
*/
public class LinkedListMap<K, V> implements Map<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);
}
@Override
public String toString(){
return key.toString() + " : " + value.toString();
}
}
//虚拟头结点
private Node dummyHead;
//大小
private int size;
/**
* 获取指定key的Node节点
* @param key 键名
* @return 存在返回Node,不存在返回null
*/
private Node getNode(K key){
Node cur = dummyHead.next;
//循环遍历获取节点键名并判断
while (cur != null){
if (cur.key == key){
return cur;
}
cur = cur.next;
}
return null;
}
@Override
public void add(K key, V value) {
//尝试获取相同的节点
Node node = getNode(key);
//如果不存在节点,则直接添加在头结点之后
if (node == null){
dummyHead.next = new Node(key,value,dummyHead.next);
size++;
// Node oldDummyHeadNextHead = dummyHead.next;
// Node dummyHeadNextHead = new Node(key,value);
// dummyHead.next = dummyHeadNextHead;
// dummyHeadNextHead.next = oldDummyHeadNextHead;
//这四步和上面的一步是同样的效果
//1.获取原头结点的下一个节点node1
//2.创建新的节点 node2
//3.将新的节点赋值为头结点的下一个节点
//4.将node2的下一个节点设置为node1
}else {
//覆盖原来的值
node.value = value;
}
}
@Override
public V remove(K key) {
Node prev = dummyHead;
//获取到正确的节点
while (prev.next != null){
if ( prev.next.key.equals(key)){
break;
}
//移动节点到下一个节点
prev = prev.next;
}
if (prev.next != null){
Node delNode = prev.next;
//删除节点的核心 也可写作 prev.next = prev.next.next
prev.next = delNode.next;
//释放内存
delNode.next = null;
size --;
return delNode.value;
}
return null;
}
@Override
public boolean contains(K key) {
return getNode(key) != null;
}
@Override
public V get(K key) {
Node node = getNode(key);
return node == null ? null:node.value;
}
@Override
public void set(K key, V newValue) {
Node node = getNode(key);
if(node == null) {
throw new IllegalArgumentException(key + " doesn't exist!");
}
node.value = newValue;
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size==0;
}
}
测试类
package queue;
import java.util.Random;
/**
* @author panghu
* @title: Main
* @projectName Algorithm_And_Data_Structure
* @date 19-7-8 上午10:47
*/
public class Main {
private static double testHeap(Integer[] testData, boolean isHeapify){
long startTime = System.nanoTime();
MaxHeap<Integer> maxHeap;
if(isHeapify)
maxHeap = new MaxHeap<>(testData);
else{
maxHeap = new MaxHeap<>();
for(int num: testData)
maxHeap.add(num);
}
int[] arr = new int[testData.length];
for(int i = 0 ; i < testData.length ; i ++)
arr[i] = maxHeap.extractMax();
for(int i = 1 ; i < testData.length ; i ++)
if(arr[i-1] < arr[i])
throw new IllegalArgumentException("Error");
System.out.println("Test MaxHeap completed.");
long endTime = System.nanoTime();
return (endTime - startTime) / 1000000000.0;
}
public static void main(String[] args) {
int n = 1000000;
Random random = new Random();
Integer[] testData = new Integer[n];
for(int i = 0 ; i < n ; i ++)
testData[i] = random.nextInt(Integer.MAX_VALUE);
double time1 = testHeap(testData, false);
System.out.println("Without heapify: " + time1 + " s");
double time2 = testHeap(testData, true);
System.out.println("With heapify: " + time2 + " s");
}
}
测试效果
Test MaxHeap completed.
Without heapify: 1.058503166 s
Test MaxHeap completed.
With heapify: 0.77208444 s
网友评论