数据结构与算法_05【集合与映射】

1.集合(Set)

集合:存储不重复元素的容器

有序集合中的元素具有顺序性,基于搜索树实现

无序集合中的元素没有顺序性,基于哈希表实现

顺序性,是指按照元素的大小进行排序,并非指插入的顺序

有序性,是指元素的进场顺序和出场顺序一致

应用场合: 客户统计 词汇量统计
Set集合接口定义

public interface Set<E> {
	public void add(E e); 	 //向集合中添加元素e(不能添加重复元 素)
	public void remove(E e);	//删除集合中指定元素e 
	public boolean contains(E e);	 //判断是否包含指定元素e 
	public int getSize();	//获取集合中元素的个数 
	public boolean isEmpty();	//判断集合是否为空 
}

BSTSet基于二分搜索树实现的集合类定义

public class BSTSet<E extends Comparable<E>> implements Set<E> {
	private BinarySearchTree<E> bst;
	public BSTSet() {
		bst=new BinarySearchTree<>();
	}
	@Override
	public void add(E e) {//O(logn)->O(n)
		bst.add(e);
	}

	@Override
	public void remove(E e) {//O(logn)
		bst.remove(e);
	}

	@Override
	public boolean contains(E e) {//O(logn)
		return bst.contains(e);
	}
	//O(nlogn) 
	@Override
	public int getSize() {
		return bst.size();
	}

	@Override
	public boolean isEmpty() {
		return bst.isEmpty();
	}
	@Override
	public String toString() {
		
		return bst.toString();
	}
}

LinkedListSet基于链表实现的集合类定义

//基于链表实现的集合
public class LinkedSet<E> implements Set<E>{
	private LinkedList<E> list;
	public LinkedSet() {
		list=new LinkedList<>();
	}
	@Override
	public void add(E e) {	//O(n)
		if(!list.contains(e)){
			list.addLast(e);//O(1)
		}
	}

	@Override
	public void remove(E e) {//O(n)
		list.removeElement(e);
	}

	@Override
	public boolean contains(E e) {//O(n)
		return list.contains(e);
	}

	@Override
	public int getSize() {
		return list.getSize();
	}
	@Override
	public boolean isEmpty() {
		return list.isEmpty();
	}
}

读取小说中的单词,对比两种不同的实现方式(时间复杂度分析)
 

public class Main2 {
	public static void main(String[] args) {
		ArrayList<String> words=new ArrayList<>();
		FileOperation.readFile("pride-and-prejudice.txt", words);
		long start=System.currentTimeMillis();
//		LinkedMap<String, Integer> map=new LinkedMap<>();
		BSTMap<String, Integer> map=new BSTMap<>();
		for(int i=0;i<words.size();i++){
			String word=words.get(i);
			if(map.contains(word)){
				map.set(word, map.get(word)+1);
			}else{
				map.add(word, 1);
			}
		}
		long end=System.currentTimeMillis();
		double second=(end-start)/1000.0;
		System.out.println("用时:"+second);
		System.out.println("map的长度:"+map.getSize());
		System.out.println("she:"+map.get("she"));
		System.out.println(map.keys());
	}
}

Java中对于集合相关的常见内置类有哪些 

 

2.映射(Map)  

 

映射就是存储(键,值)数据对的数据结构(Key,Value)。根据键(Key),寻找 值(Value)

有序映射中的键具有顺序性,基于搜索树实现

无序映射中的键没有顺序性,基于哈希表实现

Map接口定义 

public interface Map<K,V>{
	public void add(K key,V value);
	public V remove(K key);
	public boolean contains(K key);
	public V get(K key);
	public void set(K key,V value);
	public int getSize();
	public boolean isEmpty();
	public Set keys();		//返回映射中键的集合
	public List values();	//返回映射中值的线性表
}

LinkedListMap基于链表实现的映射类定义

1.定义类 

public class LinkedMap<K,V> implements Map<K,V>

2.定义内部类结点 

//基于动态链表实现的映射
public class LinkedMap<K,V> implements Map<K,V>{
	private class Node{
		public K key;
		public V value;
		public Node next;
		public Node(K key,V value){
			this.key=key;
			this.value=value;
			next=null;
		}
		public Node(){
			this(null,null);
		}
		@Override
		public String toString() {
			return key.toString()+":"+value.toString();
		}
	}

3.定义成员变量
 

private Node head; 

private int size;

4.定义构造函数

public LinkedListMap() { 
       head=new Node(); 
        size=0; 
    }

5.实现功能 

private Node getNode(Node node, K key) {
		if(node==null){
			return null;
		}
		if(node.key.equals(key)){
			return node;
		}else{
			return getNode(node.next,key);
		}
	}
	
	@Override
	public void add(K key, V value) {
		Node n=getNode(key);
		if(n==null){
			n=new Node(key,value);
			n.next=head.next;
			head.next=n;
			size++;
		}else{
			n.value=value;
		}
	}

	@Override
	public V remove(K key) {
		Node pre=head;
		while(pre.next!=null){
			if(pre.next.key.equals(key)){
				break;
			}
			pre=pre.next;
		}
		if(pre.next!=null){
			Node n=pre.next;
			pre.next=n.next;
			n.next=null;
			size--;
			return n.value;
		}
		return null;
	}

	@Override
	public boolean contains(K key) {
		return getNode(key)!=null;
	}

	@Override
	public V get(K key) {
		Node n=getNode(key);
		return n==null?null:n.value;
	}

	@Override
	public void set(K key, V value) {
		Node n=getNode(key);
		if(n==null){
			throw new IllegalArgumentException("元素不存在!");
		}
		n.value=value;
	}

	@Override
	public int getSize() {
		return size;
	}

	@Override
	public boolean isEmpty() {
		return size==0;
	}

	@Override
	public Set keys() {
		Set<K> set=new LinkedSet<K>();
		Node cur=head.next;
		while(cur!=null){
			set.add(cur.key);
		}
		return set;
	}

	@Override
	public List values() {
		List<V> list=new LinkedList<V>();
		Node cur=head.next;
		while(cur!=null){
			list.addLast(cur.value);
		}
		return list;
	}

BSTMap基于二分搜索树实现的映射类定义

1.定义类

public class BSTMap<K extends Comparable<K>,V> implements Map<K, V>

2.定义内部类结点 

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;
		}
		public Node(){
			this(null,null);
		}
		@Override
		public String toString() {
			return key.toString()+":"+value.toString();
		}
	}

3.定义成员变量 

    private Node root;	
	private int size;

4.定义构造函数

public BSTMap() {
		root=null;
		size=0;
	}

5.实现功能

@Override
	public void add(K key, V value) {
		root=add(root,key,value);
	}
	// 以node为根节点,将键值对k-v添加在树中 并返回新树的根
	private Node add(Node node,K key,V value){
		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{
			node.value=value;
		}
		return node;
	}

	@Override
	public V remove(K key) {
		Node n=getNode(root,key);
		if(n==null){
			return null;
		}
		root=remove(root,key);
		return n.value;
	}
	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{//相等
			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=minmum(node.right);
			successor.right=removeMin(node.right);
			successor.left=node.left;
			node.left=node.right=null;
			return successor;
		}
	}
	private Node minmum(Node node){
		if(node.left==null){
			return node;
		}else{
			return minmum(node.left);
		}
	}
	private Node removeMin(Node node){
		if(node.left==null){
			Node rightNode=node.right;
			size--;
			node.right=null;
			return rightNode;
		}
		node.left=removeMin(node.left);
		return node;
	}
	@Override
	public boolean contains(K key) {
		Node n=getNode(root,key);
		return n==null?false:true;
	}

	@Override
	public V get(K key) {
		Node n=getNode(root,key);
		return n==null?null:n.value;
	}

	@Override
	public void set(K key, V value) {
		Node n=getNode(root,key);
		if(n==null){
			throw new IllegalArgumentException("元素不存在!");
		}
		n.value=value;
	}

	@Override
	public int getSize() {
		return size;
	}

	@Override
	public boolean isEmpty() {
		return size==0;
	}

	@Override
	public Set keys() {
		Set<K> set=new BSTSet<>();
		inOrder(root,set);
		return set;
	}
	private void inOrder(Node node, Set<K> set) {
		if(node==null){
			return;
		}
		inOrder(node.left, set);
		set.add(node.key);
		inOrder(node.right, set);
	}

	@Override
	public List values() {
		return null;
	}
	private Node getNode(Node node,K key){
		if(node==null){
			return null;
		}
		if(key.compareTo(node.key)<0){
			return getNode(node.left,key);
		}else if(key.compareTo(node.key)>0){
			return getNode(node.right,key);
		}else{
			return node;
		}
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值