基於數組的詞典
詞典(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));
}
}