映射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();
}

用链表实现映射

     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) {this(key,null,null);}
    	public Node() {this(null,null,null);}
    	
    	public String toString() {
    		return key.toString()+":"+value.toString();
    	}
    	private Node dummyHead;
    	private int size;
    	
    	public LinkedListMap() {
    		dummyHead=new Node();
    		size=0;
    	}
    	public int getSize() {return size;}
    	
    	public boolean isEmpty() {return size==0;}
    	
    	private Node getNode(K key) {
    		Node cur=dummyHead.next;
    		while(cur!=null) {
    			if(cur.key.equals(key))
    				return cur;
    			cur=cur.next;
    		}
    		return null;
    	}
    	
    	public boolean contains(K key) {
    		return getNode(key)!=null;
    	}
    	
    	public V get(K key) {
    		Node node=getNode(key);
    		return node==null?null:node.value;
    	}
    	
    	public void add(K key,V value) {
    		Node node=getNode(key); //看是否已经有了这个数据
    		if(node==null) {
    			dummyHead.next=new Node(key,value,dummyHead.next);//链表头添加
    			size++;
    		}
    		else //若已经有这个键值对了
    			node.value=value;
    	}
    	
    	public void set(K key,V newValue) { //修改
    		Node node=getNode(key); //看是否有节点
    		if(node==null)
    			throw new IllegalArgumentException("doesn't exist!");
    		node.value=newValue;	
    	}
    	
    	public V remove(K key) {
    	    Node prev=dummyHead;
    	    while(prev.next!=null) {
    	    	if(prev.next.key.equals(key))
    	    		break;
    	    	prev=prev.next;//prev.next为要删除的节点
    	    }
    	    if(prev.next!=null) {
    	    	Node delNode=prev.next;
    	    	prev.next=delNode.next;
    	    	delNode.next=null;
    	    	size--;
    	    	return delNode.value;
    	    }
    	    return null;//如果没发现要删的
    	}

用BST实现映射

public class BSTMap<K extends Comparable<k>,v>implements Map<K,V> {
	
private class Node{
	
	public K key;
	public v value;
	public Node left,right;
	
	public Node(K key,V value) {
		this.key=key;
		this.value=value;
		left=null;
		right=null;
	}
	}
	private Node root;
	private int size;
	
	public BSTMap() {
		root=null;
		size=0;
	}
	
	public int getSize() {
		return size;
	}
	
	public boolean isEmpty() {
		return size==0;
	}
	public void add(K key,V value) {
		root=add(root,key,value);
	}
	private Node add(Node node,K key,V value) {//返回Node类型的值
	    if(node==null) { //求解最基本问题
	   		size++;
	   		return new Node(key,value);
	   	}
	   	if(key.compareTo(node.key)<0) 
	   		node.left=add(node.left,key,value);//左节点为递归值
	   	else if(key.compareTo(node.key)>0) 
	        node.right=add(node.right,key,value);
	   	else //key.compareTO(node.key)==0
	   		node.value=value;
	   	return node; //返回根节点
	}

 //返回以node为根节点的二分搜索树中,key所在的节点
	private Node getNode(Node node,K key) {
		if(node==null)
			return null;
		if(key.compareTo(node.key)==0)
			return node;
		else if( key.compareTo(node.key)<0)
			return getNode(node.left,key);
		else
			return getNode(node.right,key);
	}
	public boolean contains(K key) {
		return getNode(root,key)!=null;
	}
	public V get(K key) {
		Node node=getNode(root,key);
		return node==null?null:node.value;
	}
	
	public void set(K key,V newValue) {
		Node node=getNode(root,key);//看看key在不在
		if(node==null)
			throw new IllegalArgumentException(key+"doesn't exist");
		node.value=newValue;
			
	}
	
	
	//返回以node为根的二分搜索树最小键值所在节点
	private Node minimum(Node node) {
		if(node.left==null)
			return node;
		return minimum(node.left);
	}
	
	//从二分搜索树中删除最小值所在节点,返回最小值	
	public E removeMin() {
		E ret =minimum();
		root=removeMin(root);
		return ret;
	}
	//删除以node为根的二分搜索树最小节点
	//返回删除节点后新的二分搜索树的根
	private Node removeMin(Node node) {
		if(node.left==null) {
			Node rightNode=node.right;
			node.right=null;//与当前节点脱离关系
			size--;
			return rightNode;
		}
		node.left=removeMin(node.left);
		return node; 	
	}
	
	//从二分搜索树中删除元素为e的节点
	public V  remove(K key) {
		
	    Node node=getNode(root,key);
	    if(node!=null) {
	    	root = remove(root,e);
	    	return node.value;
	    }
	    return null;
		
	}

	//删除以node为根的二分搜索树中键为key的节点,递归算法
	//返回删除节点后新的二分搜索树的根

	private Node remove(Node node, K key) {
		if(node==null)
			return null;
		if(key.compareTo(node.key)<0) {
			node.left=remove(node.left,key);
			return node;
		}
		else if(key.compareTo(node.key)>0) {
			node.right=remove(node.right,key);
			return node;
		}
		else {  //key==node.key
			//待删除节点左子树为空的情况
			if(node.left==null) {
				Node rightNode=node.right;
				node.right=null;
				size--;
				return rightNode;
			}
			//待删除节点左子树为空的情况
			if(node.right==null) {
				Node leftNode=node.left;
				node.left=null;
				size--;
				return leftNode;
			}
			//待删除节点左右子树均不为空的情况
			//找到比这个待删除节点大的最小节点,即待删除节点右字数的的最小节点
			//用这个节点顶替待删除节点位置
			Node successor = minimum(node.right);
			successor.right=removeMin(node.right);//新的代替的节点右子树为删除最小值的树
			successor.left =node.left;
			node.left=node.right=null;
			return successor;
		}
// 测试:每个词的词频		
		public static void main(String[] args) {
    		System.out.println("Pride and Prejudice");
    		
    		ArrayList<String> words=new ArrayList<>();
    		if(FileOperation.readFile("nnnn.txt",words)) {
    			System.out.println("totel words:"+words.size());
    			BSTMap<String,Integer> map =new BSTMap<>();
    			for(String word:words) {
    				if(map.contains(word))
    					map.set(word,map.get(word)+1);// 当前word频率+1
    				else
    					map.add(word,1); //没有就添加
    			}
    			System.out.println("totel different words:"+map.getSize());
    			System.out.println("frequency of pride"+map.get("pride");)
    			
    		}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
unordered_map底层实现一般是基于哈希表(Hash Table)。哈希表是一种使用哈希函数将键映射存储位置的数据结构。 在C++中,unordered_map是标准库中的一个关联容器,它提供了键值对的映射。它的底层实现使用了哈希表来实现快速查找和插入。 具体地说,unordered_map使用一个数组来存储元素,这个数组被称为桶(buckets)。每个桶中存放了一个链表或者红黑树,用来解决哈希冲突(不同的键对应相同的哈希值)的问题。 当插入一个键值对时,unordered_map首先会计算出键的哈希值,然后通过哈希函数将哈希值映射为桶的索引。如果该桶为空,就直接将键值对插入到这个桶中;如果桶中已经存在其他键值对,就使用键进行比较来判断是否已经存在相同的键,如果有相同的键,则更新对应的值;如果没有相同的键,则将新的键值对插入到链表或者红黑树中。 在查找一个键值对时,unordered_map首先计算出键的哈希值,并通过哈希函数找到对应的桶。然后在桶中进行搜索,如果是链表,则按顺序比较键值对的键;如果是红黑树,则使用树的搜索算法来查找。 哈希表的优点是可以在平均情况下实现常数时间的插入、删除和查找操作。然而,它的缺点是对内存的利用率相对较低,并且在最坏情况下,时间复杂度可能退化为O(n),其中n是存储的键值对的数量。 这就是unordered_map底层实现的简要介绍,它使用哈希表来实现快速查找和插入,并且处理了哈希冲突的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值