基于数组的词典
词典(Dictionary),也称映射(map),词典中每个元素都由两部分组成:一个关键字,通常称为查找键(search key);一个与该键值相关联的值,一般将它们称之为键值对。每一个查找键在词典中是唯一的,即不存在两个相同的查找键,这样就可以通过查找建来访问其对应的值。
基于数组实现的词典中的每个元素必须是Entry类的一个实例,即键值对封装在一个对象中,如下图:
词典接口
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 Iterator<V> getValueIterator();
public boolean isEmpty();
public boolean isFull();
public int getSize();
public void clear();
public void display1();
public void display2();
}
基于数组的无序词典
词典中每一个元素是Entry类的一个实例,可以让这个类对词典类来说是私有的。利用泛型定义参数类型为K和V,这些参数分别表示查找建及其关联值的数据类型。
由于查找键是无序的,所以插入、删除和检索元素需要连续对比查找;又因为是无序,插入或删除一个元素时无需移动任何元素。
插入:添加元素时,首先定位该查找键是否存在,若不存在,可插入到最后一个元素的后面;若已存在,则用新值替换。
删除:删除元素时,首先定位该查找键的位置,然后用最后一个元素替换它,这样就无需移动其他元素就可以填充数组中的空洞。由于词典大小减1了,最后一个元素将会被忽略。
public class Array_UnsortedDictionary<K,V> implements DictionaryInterface<K,V>{
private Entry<K,V>[] dictionary;
private int currentSize;
private final static int DEFAULT_CAPACITY=20;
public Array_UnsortedDictionary(){
this(DEFAULT_CAPACITY);
}
@SuppressWarnings("unchecked")
public Array_UnsortedDictionary(int c) {
dictionary=new Entry[c];
currentSize=0;
}
private int locateIndex(K key){
int index=0;
while(index<currentSize && !key.equals(dictionary[index].getKey()))
index++;
return index;
}
public boolean isArrayFull() {
return currentSize==dictionary.length;
}
private void doubleArray(){
Entry<K,V>[] oldDictionary=dictionary;
dictionary=new Entry[2*oldDictionary.length];
System.arraycopy(oldDictionary, 0, dictionary, 0, oldDictionary.length);
}
@Override
public V add(K key, V value) {
V result=null;
int keyIndex=locateIndex(key);
if(keyIndex<currentSize){
result=dictionary[keyIndex].getValue();
dictionary[keyIndex].setValue(value);
}else{
if(isArrayFull())
doubleArray();
dictionary[currentSize]=new Entry<K,V>(key, value);
currentSize++;
}
return result;
}
@Override
public V remove(K key) {
V result=null;
int keyIndex=locateIndex(key);
if(keyIndex<currentSize){
result=dictionary[keyIndex].getValue();
dictionary[keyIndex]=dictionary[currentSize-1];
currentSize--;
}
return result;
}
@Override
public V getValue(K key) {
V result=null;
int keyIndex=locateIndex(key);
if(keyIndex<currentSize){
result=dictionary[keyIndex].getValue();
}
return result;
}
@Override
public boolean contains(K key) {
boolean result=false;
int keyIndex=locateIndex(key);
if(keyIndex<currentSize)
result=true;
return result;
}
@Override
public boolean isEmpty() {
return currentSize==0;
}
@Override
public boolean isFull() {
return false;
}
@Override
public int getSize() {
return currentSize;
}
@Override
public void clear() {
currentSize=0;
}
@Override
public void display1() {
Iterator iterator=getValueIterator();
while(iterator.hasNext()){
System.out.print(iterator.next()+" ");
}
System.out.println();
}
@Override
public void display2() {
for(int i=0;i<currentSize;i++){
System.out.print(dictionary[i].getKey()+","+dictionary[i].getValue()+" ");
}
System.out.println();
}
@Override
public Iterator<V> getValueIterator() {
return new IteratorForArrayList();
}
private class IteratorForArrayList<V> implements Iterator<V>{
private int index;
public IteratorForArrayList() {
index=0;
}
@Override
public boolean hasNext() {
return index<currentSize;
}
@Override
public V next() {
if(hasNext()){
V nextEntry= (V) dictionary[index].getValue();
index++;
return nextEntry;
}else
throw new NoSuchElementException("");
}
}
private class Entry<K,V> implements Serializable{
private K key;
private V value;
private Entry(K searchKey,V dataValue) {
key=searchKey;
value=dataValue;
}
private K getKey(){
return key;
}
private V getValue(){
return value;
}
private void setValue(V newValue){
value=newValue;
}
}
}
测试代码
public class main_UnsortedDictionary {
private static Array_UnsortedDictionary<Integer,Integer> list;
public static void main(String[] args) {
list=new Array_UnsortedDictionary<>();
Random ra =new Random();
for(int i=0;i<30;i++)
list.add(i,ra.nextInt(100));
list.display1();
list.add(3,235);
list.display1();
list.remove(5);
list.display1();
System.out.println(list.getValue(7));
}
}
基于数组的有序词典
有序词典的查找键必须实现Comparable接口,这样就可以对它排序。标识符<K extends Comparable<? super K>定义了通用类型K,这使得可以把K类型的对象与K类型的对象或K的任意超类的对象进行比较。
对于有序词典,定位查找键时可采用对分查找。
插入:添加元素时,首先定位该查找键是否存在,若不存在,则插入到定位的位置,并将后面的数据后移;若已存在,则用新值替换。
删除:删除元素时,首先定位该查找键的位置,然后返回定位位置的值,将后面的数据前移。
public class Array_Sorted_Dictionary<K extends Comparable<? super K>,V> implements DictionaryInterface<K, V>{
private Entry<K,V>[] dictionary;
private int currentSize;
private final static int DEFAULT_CAPACITY=20;
public Array_Sorted_Dictionary(){
this(DEFAULT_CAPACITY);
}
public Array_Sorted_Dictionary(int c) {
dictionary=new Entry[c];
currentSize=0;
}
/* private int locateIndex(K key){
int index=0;
while(index<currentSize && key.compareTo(dictionary[index].getKey())>0)
index++;
return index;
}*/
private int locateIndex(K key){
return binarySearch(0,currentSize-1, key);
}
public int binarySearch(int first,int last,K key){
int result = 0;
if(first>last)
result=first;
else{
int mid=(first+last)/2;
if(key.compareTo(dictionary[mid].getKey())==0){
result=mid;
}else if(key.compareTo(dictionary[mid].getKey())<0){
result=binarySearch(first, mid-1, key);
}else
result=binarySearch(mid+1, last, key);
}
return result;
}
public boolean isArrayFull() {
return currentSize==dictionary.length;
}
private void doubleArray(){
Entry<K,V>[] oldDictionary=dictionary;
dictionary=new Entry[2*oldDictionary.length];
System.arraycopy(oldDictionary, 0, dictionary, 0, oldDictionary.length);
}
public void makeRoom(int index){
for(int i=currentSize;i>index;i--){
dictionary[i]=dictionary[i-1];
}
}
public void removeRoom(int index){
for(int i=index;i<currentSize;i++)
dictionary[i]=dictionary[i+1];
}
@Override
public V add(K key, V value) {
System.out.print("["+key+","+value+"]"+" ");
V result=null;
int keyIndex=locateIndex(key);
if(keyIndex<currentSize && key.compareTo(dictionary[keyIndex].getKey())==0){
result=dictionary[keyIndex].getValue();
dictionary[keyIndex].setValue(value);
}else{
if(isArrayFull())
doubleArray();
makeRoom(keyIndex);
dictionary[keyIndex]=new Entry<K,V>(key, value);
currentSize++;
}
return result;
}
@Override
public V remove(K key) {
V result=null;
int keyIndex=locateIndex(key);
if(keyIndex<currentSize && key.compareTo(dictionary[keyIndex].getKey())==0){
result=dictionary[keyIndex].getValue();
removeRoom(keyIndex);
currentSize--;
}
return result;
}
@Override
public V getValue(K key) {
V result=null;
int keyIndex=locateIndex(key);
if(keyIndex<currentSize && key.compareTo(dictionary[keyIndex].getKey())==0){
result=dictionary[keyIndex].getValue();
}
return result;
}
@Override
public boolean contains(K key) {
return locateIndex(key)<currentSize;
}
@Override
public Iterator<V> getValueIterator() {
return new IteratorForArrayList();
}
@Override
public boolean isEmpty() {
return currentSize==0;
}
@Override
public boolean isFull() {
return false;
}
@Override
public int getSize() {
return currentSize;
}
@Override
public void clear() {
currentSize=0;
}
@Override
public void display1() {
Iterator iterator=getValueIterator();
while(iterator.hasNext()){
System.out.print(iterator.next()+" ");
}
System.out.println();
}
@Override
public void display2() {
System.out.println();
for(int i=0;i<currentSize;i++){
System.out.print("["+dictionary[i].getKey()+","+dictionary[i].getValue()+"]"+" ");
}
System.out.println();
}
private class IteratorForArrayList<V> implements Iterator<V>{
private int index;
public IteratorForArrayList() {
index=0;
}
@Override
public boolean hasNext() {
return index<currentSize;
}
@Override
public V next() {
if(hasNext()){
V nextEntry= (V) dictionary[index].getValue();
index++;
return nextEntry;
}else
throw new NoSuchElementException("");
}
}
private class Entry<S,T>{
private S key;
private T value;
private Entry(S searchKey,T dataValue) {
key=searchKey;
value=dataValue;
}
private S getKey(){
return key;
}
private T getValue(){
return value;
}
private void setValue(T newValue){
value=newValue;
}
}
}
测试代码
public class main_SortedDictionary {
private static Array_Sorted_Dictionary<Integer,Integer> list;
public static void main(String[] args) {
list=new Array_Sorted_Dictionary<Integer, Integer>();
Random ra =new Random();
for(int i=0;i<10;i++)
list.add(ra.nextInt(100),ra.nextInt(100));
list.display2();
list.remove(26);
list.display1();
System.out.print(list.getValue(45));
}
}