集合和映射
集合
-
和數學裏面定義一樣:無序,不重複
-
裏面的具體的包裝類BST:二分搜索樹和鏈表之前已經發過
package 數據結構.set; import 數據結構.BST.BST; //使用二分搜索樹來進行集合表達 public class BSTSet<E extends Comparable<E>> implements Set<E> { private BST<E> bst; public BSTSet(){ bst=new BST<>(); } @Override public int getSize() { return bst.getSize(); } @Override public boolean isEmpty() { return bst.isEmpty(); } @Override public void add(E e) { bst.add(e); } @Override public boolean contains(E e) { return bst.contains(e); } @Override public void remove(E e) { bst.remove(e); } } package 數據結構.set; import 數據結構.LinkedList.LinkedList; import java.util.ArrayList; //使用鏈表進行表示集合 public class LinkedListSet<E> implements Set<E> { private LinkedList<E> list; public LinkedListSet(){ list = new LinkedList<>(); } @Override public int getSize() { return list.getSize(); } public boolean isEmpty(){ return list.isEmpty(); } @Override public boolean contains(E e) { return list.contains(e); } @Override public void add(E e) { if(!list.contains(e)) list.addFirst(e); } @Override public void remove(E e) { list.removeElement(e); } public static void main(String[] args) { System.out.println("Pride and Prejudice"); ArrayList<String> words1 = new ArrayList<>(); FileOperation.readFile("C:\\Users\\admin\\IdeaProjects\\untitled1\\src\\數據結構\\set\\pride-and-prejudice.txt",words1); LinkedListSet<String> set1 = new LinkedListSet<>(); for (String word:words1) { set1.add(word); } System.out.println(set1.getSize()); System.out.println(words1.size()); } }
-
通過複雜度分析:我們可以明顯知道,以二叉樹來表示集合,速度更快,而使用鏈表時間複雜度高的多
映射(map)
-
俗稱:字典或者鍵值對
-
也有兩種處理方式:鏈表映射和二叉樹映射
-
鏈表映射:
package 數據結構.map; import 數據結構.LinkedList.LinkedList; import java.security.Key; import java.util.ArrayList; import java.util.Set; import java.util.function.ToDoubleBiFunction; public class LinkedListMap<K,V>implements Map<K,V> { public 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; } @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+"doesn't exist!"); 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> words = new ArrayList<>(); if(FileOperation.readFile("C:\\Users\\admin\\IdeaProjects\\untitled1\\src\\數據結構\\map\\pride-and-prejudice.txt",words)) { System.out.println("Total words: "+words.size()); LinkedListMap<String,Integer> map = new LinkedListMap<>(); for (String word:words) { if (map.contains(word)) { map.set(word,map.get(word)+1); } else{ map.add(word,1); } } System.out.println(map.getSize()); } } }
-
二分搜索樹映射
package 數據結構.map; import java.nio.channels.ClosedSelectorException; import java.security.PublicKey; import java.util.ArrayList; 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; } @Override public int getSize() { return size; } @Override public boolean isEmpty() { return size==0; } //向二分搜索樹中添加新的元素 @Override public void add(K key, V value) { root = add(root,key,value); } //向以node爲根的二分搜索樹中插入元素,使用遞歸算法 //返回插入新節點後的二分搜索樹的根 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; } //返回以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); } @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.left == 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); } //刪除最小節點 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; } //在樹中刪除節點的方法 @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; } else if (key.compareTo(node.key) > 0) { node.right = remove(node.right, key); return node; } else {//k==node.e //待刪除節點左子樹爲空 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("C:\\Users\\admin\\IdeaProjects\\untitled1\\src\\數據結構\\map\\pride-and-prejudice.txt",words)) { System.out.println("Total words: "+words.size()); BSTMap<String,Integer> map = new BSTMap<>(); for (String word:words) { if (map.contains(word)) { map.set(word,map.get(word)+1); } else{ map.add(word,1); } } System.out.println(map.getSize()); } } }
-
集合和映射,使用原理大概一樣