基于链表的词典
词典(Dictionary),也称映射(map),词典中每个元素都由两部分组成:一个关键字,通常称为查找键(search key);一个与该键值相关联的值,一般将它们称之为键值对。每一个查找键在词典中是唯一的,即不存在两个相同的查找键,这样就可以通过查找建来访问其对应的值。
就像上一篇
基于数组的词典,每个元素可以是Entry类的一个实例,即键值对封装在一个对象中,如下图
另外一种是不使用Entry类,而是定义私有Node类,其包含3个数据域key、value、next。
词典接口
public interface DictionaryInterface<K,V> {
public V add(K key,V value);
public V remove(K key);
public V getValue(K key);
public boolean contains(K key);
public boolean isEmpty();
public boolean isFull();
public int getSize();
public void clear();
public void display();
public Iterator<K> getKeyIterator();
public Iterator<V> getValueIterator();
}
基于链表的无序词典
插入和删除操作的效率本应该是O(1),但防止出现重复查找键需要从链表的始端开始顺序查找,因此最快情况下的效率为O(n)。
插入:添加元素时,首先定位该查找键是否存在,若不存在,直接插入到链头,若存在,则替换该位置的值
删除:删除元素时,首先定位该查找键是否存在,若不存在,则返回null,若存在,则删除该位置的元素
public class Linked_Unsorted_Dictionary<K,V> implements DictionaryInterface<K, V>{
private Node firstNode;
private int currentSize;
public Linked_Unsorted_Dictionary() {
firstNode=null;
currentSize=0;
}
@Override
public V add(K key, V value) {
System.out.print("["+key+","+value+"]"+" ");
V result=null;
Node currentNode=firstNode;
while(currentNode!=null && !key.equals(currentNode.getKey()))
currentNode=currentNode.getNextNode();
if(currentNode!=null && key.equals(currentNode.getKey())){
result=currentNode.getValue();
currentNode.setValue(value);
}else{
Node newNode=new Node(key, value);
newNode.setNextNode(firstNode);
firstNode=newNode;
currentSize++;
}
return result;
}
@Override
public V remove(K key) {
V result=null;
Node currentNode=firstNode;
Node beforeNode=null;
while(currentNode!=null && !key.equals(currentNode.getKey())){
beforeNode=currentNode;
currentNode=currentNode.getNextNode();
}
if(currentNode!=null && key.equals(currentNode.getKey())){
result=currentNode.getValue();
beforeNode.setNextNode(currentNode.getNextNode());
currentSize--;
}
return result;
}
@Override
public V getValue(K key){
V result=null;
Node currentNode=firstNode;
while(currentNode!=null && !key.equals(currentNode.getKey()))
currentNode=currentNode.getNextNode();
if(currentNode!=null && key.equals(currentNode.getKey()))
result=currentNode.getValue();
return result;
}
@Override
public boolean contains(K key) {
Node currentNode=firstNode;
while(currentNode!=null && !key.equals(currentNode.getKey()))
currentNode=currentNode.getNextNode();
return currentNode!=null;
}
@Override
public boolean isEmpty() {
return currentSize==0;
}
@Override
public boolean isFull() {
return false;
}
@Override
public int getSize() {
return currentSize;
}
@Override
public void clear() {
firstNode=null;
currentSize=0;
}
@Override
public void display() {
System.out.println();
Iterator keyiterator=getKeyIterator();
Iterator<V> valueiterator=getValueIterator();
while(keyiterator.hasNext() && valueiterator.hasNext()){
System.out.print("["+keyiterator.next()+","+valueiterator.next()+"]"+" ");
}
System.out.println();
}
@Override
public Iterator<K> getKeyIterator() {
return new KeyIterator();
}
@Override
public Iterator<V> getValueIterator() {
return new ValueIterator();
}
private class KeyIterator implements Iterator<K>{
private Node nextNode;
public KeyIterator() {
nextNode=firstNode;
}
@Override
public boolean hasNext() {
return nextNode!=null;
}
@Override
public K next() {
K result=nextNode.getKey();
nextNode=nextNode.getNextNode();
return result;
}
}
private class ValueIterator implements Iterator<V>{
private Node nextNode;
public ValueIterator() {
nextNode=firstNode;
}
@Override
public boolean hasNext() {
return nextNode!=null;
}
@Override
public V next() {
V result=nextNode.getValue();
nextNode=nextNode.getNextNode();
return result;
}
}
private class Node {
private K key;
private V value;
private Node next;
private Node(K key,V value) {
this(key,value,null);
}
private Node(K key,V value,Node next){
this.key=key;
this.value=value;
this.next=next;
}
private K getKey(){
return key;
}
private V getValue(){
return value;
}
private void setValue(V value){
this.value=value;
}
private Node getNextNode(){
return next;
}
private void setNextNode(Node nextNode){
next=nextNode;
}
}
}
测试代码
public class main_Unsorted_Dictionary {
private static Linked_Unsorted_Dictionary<Integer, Integer> list;
public static void main(String[] args) {
list=new Linked_Unsorted_Dictionary<Integer, Integer>();
Random ra =new Random();
for(int i=0;i<10;i++)
list.add(ra.nextInt(100),ra.nextInt(100));
list.display();
list.remove(56);
list.display();
}
}
基于链表的有序词典
public class Linked_Sorted_Dictionary<K extends Comparable<? super K>,V> implements DictionaryInterface<K, V>{
private Node firstNode;
private int currentSize;
public Linked_Sorted_Dictionary() {
firstNode=null;
currentSize=0;
}
@Override
public V add(K key, V value) {
System.out.print("["+key+","+value+"]"+" ");
V result=null;
Node currentNode=firstNode;
Node beforeNode=null;
while(currentNode!=null && key.compareTo(currentNode.getKey())>0){
beforeNode=currentNode;
currentNode=currentNode.getNextNode();
}
if(currentNode!=null && key.compareTo(currentNode.getKey())==0){
result=currentNode.getValue();
currentNode.setValue(value);
}else{
Node newNode=new Node(key, value);
currentSize++;
if(beforeNode==null){
newNode.setNextNode(firstNode);
firstNode=newNode;
}else{
newNode.setNextNode(currentNode);
beforeNode.setNextNode(newNode);
}
}
return result;
}
@Override
public V remove(K key) {
V result=null;
Node currentNode=firstNode;
Node beforeNode=null;
while(currentNode!=null && key.compareTo(currentNode.getKey())>0){
beforeNode=currentNode;
currentNode=currentNode.getNextNode();
}
if(currentNode!=null && key.compareTo(currentNode.getKey())==0){
result=currentNode.getValue();
beforeNode.setNextNode(currentNode.getNextNode());
}
return result;
}
@Override
public V getValue(K key) {
V result=null;
Node currentNode=firstNode;
while(currentNode!=null && key.compareTo(currentNode.getKey())>0)
currentNode=currentNode.getNextNode();
if(currentNode!=null && key.compareTo(currentNode.getKey())==0)
result=currentNode.getValue();
return result;
}
@Override
public boolean contains(K key) {
Node currentNode=firstNode;
while(currentNode!=null && key.compareTo(currentNode.getKey())>0)
currentNode=currentNode.getNextNode();
return currentNode!=null;
}
@Override
public boolean isEmpty() {
return currentSize==0;
}
@Override
public boolean isFull() {
return false;
}
@Override
public int getSize() {
return currentSize;
}
@Override
public void clear() {
firstNode=null;
currentSize=0;
}
@Override
public void display() {
System.out.println();
Iterator keyiterator=getKeyIterator();
Iterator<V> valueiterator=getValueIterator();
while(keyiterator.hasNext() && valueiterator.hasNext()){
System.out.print("["+keyiterator.next()+","+valueiterator.next()+"]"+" ");
}
System.out.println();
}
@Override
public Iterator<K> getKeyIterator() {
return new KeyIterator();
}
@Override
public Iterator<V> getValueIterator() {
return new ValueIterator();
}
private class KeyIterator implements Iterator<K>{
private Node nextNode;
public KeyIterator() {
nextNode=firstNode;
}
@Override
public boolean hasNext() {
return nextNode!=null;
}
@Override
public K next() {
K result=nextNode.getKey();
nextNode=nextNode.getNextNode();
return result;
}
}
private class ValueIterator implements Iterator<V>{
private Node nextNode;
public ValueIterator() {
nextNode=firstNode;
}
@Override
public boolean hasNext() {
return nextNode!=null;
}
@Override
public V next() {
V result=nextNode.getValue();
nextNode=nextNode.getNextNode();
return result;
}
}
private class Node {
private K key;
private V value;
private Node next;
private Node(K key,V value) {
this(key,value,null);
}
private Node(K key,V value,Node next){
this.key=key;
this.value=value;
this.next=next;
}
private K getKey(){
return key;
}
private V getValue(){
return value;
}
private void setValue(V value){
this.value=value;
}
private Node getNextNode(){
return next;
}
private void setNextNode(Node nextNode){
next=nextNode;
}
}
}
测试代码
public class main_SortedDictionary {
private static Linked_Sorted_Dictionary<Integer, Integer> list;
public static void main(String[] args) {
list=new Linked_Sorted_Dictionary<Integer, Integer>();
Random ra =new Random();
for(int i=0;i<10;i++)
list.add(ra.nextInt(100),ra.nextInt(100));
list.display();
list.remove(45);
list.display();
}
}
基于数组词典与基于链表词典的比较
词典各操作在最坏的情况下的效率如下表:
- 基于链表词典不需要考虑词典的长度,而基于数组词典需要
- 两种实现的各种操作的时间复杂度几乎一样,但需要认识到数组需要平移元素,而链表不需要
- 基于数组的词典因为使用二叉查找,检索操作更高效