基于链表的词典

基于链表的词典

词典(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();
	}
}

基于数组词典与基于链表词典的比较

词典各操作在最坏的情况下的效率如下表:
  • 基于链表词典不需要考虑词典的长度,而基于数组词典需要
  • 两种实现的各种操作的时间复杂度几乎一样,但需要认识到数组需要平移元素,而链表不需要
  • 基于数组的词典因为使用二叉查找,检索操作更高效




猜你喜欢

转载自blog.csdn.net/hjy132/article/details/62889863