JAVA数据结构,集合与映射

1.集合(Set)

集合:存储不重复元素的容器
有序集合中的元素具有顺序性,基于搜索树实现
无序集合中的元素没有顺序性,基于哈希表实现
顺序性,是指按照元素的大小进行排序,并非指插入的顺序
有序性,是指元素的进场顺序和出场顺序一致
应用场合:
客户统计
词汇量统计

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

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

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

import p01.动态数组.Stack;
import p02.动态链表.LinkedStack;

/*
 树:元素与元素之间存在一对多的关系 层次关系
 根节点 叶子结点 孩子结点 父亲结点
 二叉树:就是一种特殊的树结构 元素节点最多有两个孩子节点
 二叉树怎么存?动态数组 动态链表
 如果用动态数组存一个深度为h的二叉树 最多需要 2^h-1
 每一层最多几个节点 2^(h-1)
 如果此时的二叉树不是一个平衡二叉树 那么用动态数组存会有很多空间浪费
 平衡:
 满二叉树:叶子节点的深度差为0 且最后一层全是叶子结点
 完全二叉树:是按照每一层从左到右填充节点 叶子节点的深度差<=1
 满二叉树一定是完全二叉树
 完全二叉树不一定是满二叉树
 二分搜索树:就是一颗二叉树 只不过有一些条件限定 
 目前这个二分搜索树是非平衡!
 二叉搜索树 二叉排序树 二叉顺序树
 对于二叉树中的每一个结点
 其左子树中所有的结点都小于该节点
 其右子树中所有的结点都大于该节点
 相等怎么处理?不对相等做处理!不能存储重复元素

 目前为止 关于O(logn) 二分查找 插入排序 二分搜索树

 */
public class BinarySearchTree<E extends Comparable<E>> { // BST
	private class Node {
		public E e; // 节点数据域
		public Node left, right;

		public Node(E e) {
			this.e = e;
			left = null;
			right = null;
		}
	}

	private Node root; // 二分搜索树的根节点
	private int size;

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

	// 获取树中元素的个数
	public int size() {
		return size;
	}

	// 判断树是否为空
	public boolean isEmpty() {
		return size() == 0;
	}

	// 将元素e添加到树中
	public void add(E e) {
		// 迭代实现
		/*
		 * if(size()==0){ root=new Node(e); size++; } Node p=root; while(true){
		 * if(e.compareTo(p.e)==0){ return; }else if(e.compareTo(p.e)>0){
		 * if(p.right!=null){ p=p.right; }else{ p.right=new Node(e); size++;
		 * return; } }else{ if(p.left!=null){ p=p.left; }else{ p.left=new
		 * Node(e); size++; return; } } }
		 */
		root = add(root, e);
	}

	// 以node为当前树的根节点,添加元素e并返回该树的根
	private Node add(Node node, E e) {
		if (node == null) {
			size++;
			return new Node(e);
		}
		if (e.compareTo(node.e) > 0) {
			node.right = add(node.right, e);
		} else if (e.compareTo(node.e) < 0) {
			node.left = add(node.left, e);
		}
		return node;
	}

	// 查找元素e是否存在于树中
	public boolean contains(E e) {
		// 迭代实现
		/*
		 * if(size()==0){ return false; } Node p=root; while(p!=null){
		 * if(e.compareTo(p.e)>0){ p=p.right; }else if(e.compareTo(p.e)<0){
		 * p=p.left; }else{ return true; } } return false;
		 */
		return contains(root, e);
	}

	// 查找以node为根节点的树是否包含元素e
	private boolean contains(Node node, E e) {
		if (node == null) {
			return false;
		}
		if (e.compareTo(node.e) > 0) {
			return contains(node.right, e);
		} else if (e.compareTo(node.e) < 0) {
			return contains(node.left, e);
		} else {
			return true;
		}
	}

	// 中序遍历 preOrder前序 postOrder后序
	public void inOrder() {
		ArrayList<E> list = new ArrayList<E>();
		inOrder(root, list);
		System.out.println(list);
	}

	private void inOrder(Node node, ArrayList<E> list) {
		if (node == null) {
			return;
		}
		inOrder(node.left, list);
		list.add(node.e);
		inOrder(node.right, list);
	}

	// 层序遍历 广度优先遍历
	public void levelOrder() {
		ArrayList<E> list = new ArrayList<E>();
		// 用辅助队列实现层序遍历
		Queue<Node> queue = new LinkedList<Node>();
		queue.add(root);
		while (!queue.isEmpty()) {
			Node cur = queue.poll();
			list.add(cur.e);
			if (cur.left != null) {
				queue.add(cur.left);
			}
			if (cur.right != null) {
				queue.add(cur.right);
			}
		}
		System.out.println(list);
	}

	@Override
	public String toString() {
		/*StringBuilder sb=new StringBuilder();
		generateBSTString(root,0,sb);*/
		LinkedList<E> list=new LinkedList<>();
		BSTIterator it=new BSTIterator(root);
		while(it.hasNext()){
			list.addLast(it.next());
		}
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<list.size();i++){
			sb.append(list.get(i)+"\n");
		}
		return sb.toString();
	}
	private void generateBSTString(Node node, int level,
			StringBuilder sb) {
		if(node==null){
			sb.append(generateDepthString(level)+"null\n");
			return;
		}
		generateBSTString(node.left, level+1, sb);
		sb.append(generateDepthString(level)+node.e+"\n");
		generateBSTString(node.right, level+1, sb);
	}
	private String generateDepthString(int level) {
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<level;i++){
			sb.append("--");
		}
		return sb.toString();
	}
	// 获取最小值
	public E minmum(){
		if(size()==0){
			throw new IllegalArgumentException("Tree is empty!");
		}
		return minmun(root).e;
	}
	// 以node为根节点 查找该树中的最小值
	private Node minmun(Node node){
		if(node.left==null){
			return node;
		}
		return minmun(node.left);
	}
	// 获取最大值
	public E maxmun(){
		if(size()==0){
			throw new IllegalArgumentException("Tree is empty!");
		}
		return maxmum(root).e;
	}
	private Node maxmum(Node node) {
		if(node.right==null){
			return node;
		}
		return maxmum(node.right);
	}
	// 删除最小值
	public E removeMin(){
		E e=minmum();
		root=removeMin(root);
		return e;
	}
	// 以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;
	}
	// 删除最大值
	public E removeMax(){
		E e=maxmun();
		root=removeMax(root);
		return e;
	}
	private Node removeMax(Node node){
		if(node.right==null){
			Node leftNode=node.left;
			node.left=null;
			size--;
			return leftNode;
		}
		node.right=removeMax(node.right);
		return node;
	}
	public void remove(E e){
		root=remove(root,e);
	}
	// 以node为根 删除指定元素e之后 返回新树的根
	private Node remove(Node node,E e){
		if(node==null){
			return null;
		}
		if(e.compareTo(node.e)>0){
			node.right=remove(node.right,e);
			return node;
		}else if(e.compareTo(node.e)<0){
			node.left=remove(node.left,e);
			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=minmun(node.right);
			successor.right=removeMin(node.right);
			successor.left=node.left;
			node.left=node.right=null;
			return successor;
		}
	}
	class BSTIterator {
		Stack<Node> stack=new LinkedStack<>();
	    public BSTIterator(Node root) {
	        Node cur=root;
	        while(cur!=null){
	        	stack.push(cur);
	        	cur=cur.left;
	        }
	    }
	    public E next() {
	        Node n=stack.pop();
	        Node cur=n.right;
	        while(cur!=null){
	        	stack.push(cur);
	        	cur=cur.left;
	        }
	        return n.e;
	    }
	    public boolean hasNext() {
	        return !stack.isEmpty();
	    }
	}
}

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基于链表实现的集合类定义

LinkedList代码在以前写的LinkedList的数据结构中

import p02.动态链表.LinkedList;
//基于链表实现的集合
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();
	}
}

在这里插入图片描述

二分搜索树最坏情况

在这里插入图片描述

在这里插入图片描述

映射

映射就是存储(键,值)数据对的数据结构(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

package p05.集合与映射;

import p01.动态数组.List;
import p02.动态链表.LinkedList;
//基于动态链表实现的映射
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();
		}
	}
	private Node head;
	private int size;
	public LinkedMap() {
		head=new Node();
		size=0;
	}
	//为了操作方便 写一个辅助函数
	private Node getNode(K key){
		//迭代
/*		Node p=head.next;
		while(p!=null){
			if(p.key.equals(key)){
				return p;
			}
			p=p.next;
		}
		return null;*/
		return getNode(head.next,key);
	}
	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基于二分搜索树实现的映射类定义

package p05.集合与映射;

import p01.动态数组.List;

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();
		}
	}
	private Node root;	
	private int size;
	public BSTMap() {
		root=null;
		size=0;
	}
	
	@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;
		}
	}
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值