写点什么

数组结构七:集合和映射(Set And Map)

用户头像
Android架构
关注
发布于: 5 小时前

}


1.2、BSTSet.java




public class BSTSet<E extends Comparable<E>> implements Set<E> {


private BST<E> bst;


public BSTSet() {


bst = new BST<>();


}


@Override


public void add(E e) {


bst.add(e);


}


@Override


public void remove(E e) {


bst.remove(e);


}


@Override


public boolean contains(E e) {


return bst.contains(e);


}


@Override


public int getSize() {


return bst.size();


}


@Override


public boolean isEmpty() {


return false;


}


public static void main(String[] args) {


System.out.println("Pride and Prejudice");


ArrayList<String> words1 = new ArrayList<>();


FileOperation.readFile(


"D:\idea_ws\java\JavaTest1\src\com\ph\pride-and-prejudice.txt", words1);


// FileOperation.readFile(


// "..\..\..\pride-and-prejudice.txt", words1);


System.out.println("Total words: " + words1.size());


BSTSet<String> set1=new BSTSet<>();


for (String word:words1)


set1.add(word);


System.out.println("Total different words: " + set1.getSize());


}


}


1.3、LinkedListSet.java




public class LinkedListSet<E> implements Set<E> {


private LearnLinkedList<E> list;


public LinkedListSet() {


list = new LearnLinkedList<>();


}


/**


  • LearnLinkedList 可以有重复的元素

  • Set 不可以有重复的元素

  • 所以这里要稍作一些逻辑的处理


*/


@Override


public void add(E e) {


if (!list.contains(e))


list.addFirst(e);


}


@Override


public void remove(E e) {


list.removeElement(e);


}


@Override


public boolean contains(E e) {


return list.contains(e);


}


@Override


public int getSize() {


return list.getSize();


}


@Override


public boolean isEmpty() {


return list.isEmpty();


}


public static void main(String[] args) {


System.out.println("Pride and Prejudice");


ArrayList<String> words1 = new ArrayList<>();


FileOperation.readFile(


"D:\idea_ws\java\JavaTest1\src\com\ph\pride-and-prejudice.txt", words1);


System.out.println("Total words: " + words1.size());


LinkedListSet<String> set1 = new LinkedListSet<>();


for (String word : words1)


set1.add(word);


System.out.println("Total different words: " + set1.getSize());


}


}


1.4、SetMainTest.java




/**


  • 测试 BSTSet 和 LinkedListSet 的性能


*/


public class SetMainTest {


public static void main(String[] args) {


String fileName = "D:\idea_ws\java\JavaTest1\src\com\ph\pride-and-prejudice.txt";


double time1 = testSet(new BSTSet<>(), fileName);


System.out.println("BSTSet: " + time1 + "s");


System.out.println();


double time2 = testSet(new LinkedListSet<>(), fileName);


System.out.println("LinkedListSet: " + time2 + "s");


}


private static double testSet(Set<String> set, String fileName) {


long startTime = System.nanoTime();


System.out.println(fileName);


ArrayList<String> words = new ArrayList<>();


if (FileOperation.readFile(fileName, words)) {


System.out.println("Total words: " + words.size());


for (String word : words)


set.add(word);


System.out.println("Total different words: " + set.getSize());


}


long endTime = System.nanoTime();


return (endTime - startTime) / 1000000000.0;


}


}


打印结果:



可以看到 BST 二分搜索树的性能要远高于 LinkedListSet。


下面我们进行时间复杂度分析。


2、集合的时间复杂度分析


============



其中的 h 是指二分搜索树的高度,那么 h 和 n 的关系是怎么样的呢?



如下:



分析 1:



分析 2:



分析 3:



分析 4:



假设数据量为 100 万,如果一个 O(logn)算法需要一天的话,O(n)算法需要 137 年。


分析 5:



3、Map?映射


========


称映射不是那么好理解,称为字典就更好理解一点。在 Python 中,map 这种数据结构的名字就是 dict(dictionary 的缩写?字典)、



总结:


  • 存储(键,值)数据对的数据结构(Key,Value)

  • 根据 Key,寻找 Value

  • 非常容易使用链表或者二分搜索树实现


3.1、Map.java




public interface Map<K, V> {


int getSize();


boolean isEmpty();


void add(K key, V value);


V remove(K key);


boolean contains(K key);


V get(K key);


void set(K key, V newValue);


}


3.2、LinkedListMap.java




public class LinkedListMap<K, V> implements Map<K, V> {


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);


}


@Override


public String toString() {


return key.toString() + " : " + value.toString();


}


}


private Node dummyHead;


private int size;


public LinkedListMap() {


dummyHead = new Node();


size = 0;


}


@Override


public int getSize() {


return size;


}


@Override


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;


}


@Override


public boolean contains(K key) {


return getNode(key) != null;


}


@Override


public V get(K key) {


Node node = getNode(key);


return node == null ? null : node.value;


}


/**


  • 不能有两个相同的 key


*/


@Override


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;


}


@Override


public void set(K key, V newValue) {


Node node = getNode(key);


if (node == null)


throw new IllegalArgumentException(key + "不存在!");


node.value = newValue;


}


// 最复杂


@Override


public V remove(K key) {


Node prev = dummyHead;


while (prev.next != null) {


if (prev.next.key.equals(key))


break;


prev = prev.next;


}


if (prev.next != null) {


Node delNode = prev.next;


prev.next = delNode.next;


delNode.next = null;


size--;


return delNode.value;


}


return null;


}


public static void main(String[] args) {


System.out.println("Pride and Prejudice");


ArrayList<String> words1 = new ArrayList<>();


if (FileOperation.readFile(Constant.FILE_NAME, words1)) {


System.out.println("Total words: " + words1.size());


// 用来做单词频率统计,string 用于放单词,integer 用于放频率


LinkedListMap<String, Integer> map = new LinkedListMap<>();


for (String word : words1) {


if (map.contains(word))


map.set(word, map.get(word) + 1);


else


map.add(word, 1);


}


System.out.println("Total different words: " + map.getSize());


System.out.println("Frequency of PRIDE: " + map.get("pride"));


System.out.println("Frequency of PREJUDICE: " + map.get("prejudice"));


}


}


}


3.3、BSTMap.java




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;


@Override


public void add(K key, V value) {


root = add(root, key, value);


}


// 向以 node 为根的二分搜索树中插入元素(key, value),递归算法


// 返回插入新节点后二分搜索树的根


private Node add(Node node, K key, V value) {


if (node == null) {


siz


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


e++;


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.equals(node.key))


return node;


else if (key.compareTo(node.key) < 0)


return getNode(node.left, key);


else // if(key.compareTo(node.key) > 0)


return getNode(node.right, key);


}


@Override


public boolean contains(K key) {


return getNode(root, key) != null;


}


@Override


public V get(K key) {


Node node = getNode(root, key);


return node == null ? null : node.value;


}


@Override


public void set(K key, V newValue) {


Node node = getNode(root, key);


if (node == null)


throw new IllegalArgumentException(key + " doesn't exist!");


node.value = newValue;


}


@Override


public int getSize() {


return size;


}


@Override


public boolean isEmpty() {


return size == 0;


}


// 返回以 node 为根的二分搜索树的最小值所在的节点


private Node minimum(Node node) {


if (node.left == null)


return node;


return minimum(node.left);


}


// 删除掉以 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;


}


// 从二分搜索树中删除键为 key 的节点


@Override


public V remove(K key) {


Node node = getNode(root, key);


if (node != null) {


root = remove(root, key);


return node.value;


}


return null;


}


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;

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
数组结构七:集合和映射(Set And Map)