zoukankan      html  css  js  c++  java
  • 集合(基于二分搜索树的集合和基于链表的集合)

    集合的典型应用: 

    客户统计

    词汇量统计

    1、基于二分搜索树的集合

    定义接口ISet

    public interface ISet<E> {
        void add(E e);
        void remove(E e);
        boolean contains(E e);
        int getSize();
        boolean isEmpty();
    }
    

    定义基于二分搜索树的集合 

    public class BinarySearchTreeSet<E extends  Comparable<E>> implements  ISet<E> {
    
        private BinarySearchTree<E> bst;
    
        public BinarySearchTreeSet(){
            bst = new BinarySearchTree<E>();
        }
    
        public void add(E e) {
            bst.add(e);
        }
    
        public void remove(E e) {
            bst.remove(e);
        }
    
        public boolean contains(E e) {
            return bst.contains(e);
        }
    
        public int getSize() {
            return bst.size();
        }
    
        public boolean isEmpty() {
            return bst.isEmpty();
        }
    }
    

      

     2、 基于链表的集合

    public class LinkedListSet<E> implements  ISet<E> {
    
        private LinkedList<E> linkedList;
    
        public LinkedListSet(){
            linkedList= new LinkedList<E>();
        }
    
        public void add(E e) {
            if(!linkedList.contains(e)){
                linkedList.addFirst(e);
            }
    
        }
    
        public void remove(E e) {
            linkedList.removeElement(e);
        }
    
        public boolean contains(E e) {
            return linkedList.contains(e);
        }
    
        public int getSize() {
            return linkedList.getSize();
        }
    
        public boolean isEmpty() {
            return linkedList.isEmpty();
        }
    }
    

      

    3、基于二分搜索树结合和链表结合性能对比

    public class TwoSetTest {
    
        private static  double testSet(ISet<String> set){
            long startTime = System.nanoTime();
            String[] arr = {"张三", "李四","王五", "赵六","张三丰","李思明","王老五","赵明"};
            for(int i = 0; i < 5000; i++){
                for(String str : arr){
                    set.add(str +i);
                }
            }
            long endTme = System.nanoTime();
            return  (endTme - startTime) / 1000000000.0;
        }
    
        public static void main(String[] args) {
    
            BinarySearchTreeSet<String> set2 = new BinarySearchTreeSet<String>();
            double time2 =  testSet(set2);
            System.out.println("二分搜索树Set花费" + time2);
    
            LinkedListSet<String> set1 = new LinkedListSet<String>();
            double time1 =  testSet(set1);
            System.out.println("链表Set花费" + time1);
            
        }
    }
    

      

    输出结果如下:

    二分搜索树Set花费0.040670373
    链表Set花费7.014404433

    可以发现,二分搜索树的Set花费的时间明显小于基于链表的Set

    两种集合的时间复杂度比较

      LinkedListSet
    BinarySearchTreeSet
    增add  O(n)  O(h), 或者平均O(logn) 最差O(n)
    查contains  O(n)   O(h) ,或者平均O(logn) 最差O(n)
    删remove  O(n)   O(h), 或者平均O(logn) 最差O(n)

    h为数的高度。n和h的关系  h = logn , 2^h = n

    BinarySearchTreeSet 最差O(n),比如

     最差是O(n),我们可以使用平衡二叉树,这个后面再进行介绍。

    4、leetcode集合的使用题目 804 唯一摩尔斯密码词

    https://leetcode-cn.com/problems/unique-morse-code-words/

    题目描述

    国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: "a" 对应 ".-", "b" 对应 "-...", "c" 对应 "-.-.", 等等。
    
    为了方便,所有26个英文字母对应摩尔斯密码表如下:
    
    [".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]
    给定一个单词列表,每个单词可以写成每个字母对应摩尔斯密码的组合。例如,"cab" 可以写成 "-.-..--...",(即 "-.-." + ".-" + "-..." 字符串的结合)。我们将这样一个连接过程称作单词翻译。
    
    返回我们可以获得所有词不同单词翻译的数量。
    
    例如:
    输入: words = ["gin", "zen", "gig", "msg"]
    输出: 2
    解释: 
    各单词翻译如下:
    "gin" -> "--...-."
    "zen" -> "--...-."
    "gig" -> "--...--."
    "msg" -> "--...--."
    
    共有 2 种不同翻译, "--...-." 和 "--...--.".
    

      

    解决方法:

        public int uniqueMorseRepresentations(String[] words) {
    
            TreeSet<String> treeSet = new TreeSet<String>();
            String[] codes = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
            for(String word : words){
                StringBuilder res = new StringBuilder();
                for(int i = 0; i < word.length(); i++){
                    res.append(codes[word.charAt(i) - 'a']);
                }
                treeSet.add(res.toString());
            }
            return treeSet.size();
    
        }
    

      

    5、有序集合和无序集合

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

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

    6、多重集合

    集合中的元素可以重复。

    作者:Work Hard Work Smart
    出处:http://www.cnblogs.com/linlf03/
    欢迎任何形式的转载,未经作者同意,请保留此段声明!

  • 相关阅读:
    网络流
    随机化
    sw抄来的主席树
    牛客SQL题解-统计各个部门的工资记录数
    牛客SQL题解-查找所有员工自入职以来的薪水涨幅情况
    牛客SQL题解-查找薪水排名第二多的员工编号emp_no、薪水salary、last_name以及first_name,不能使用order by完成
    牛客SQL题解-查找所有员工的last_name和first_name以及对应的dept_name,也包括暂时没有分配部门的员工
    牛客SQL题解-获取薪水第二多的员工的emp_no以及其对应的薪水salary
    牛客SQL题解-统计出各个title类型对应的员工薪水对应的平均工资avg
    牛客SQL题解-查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
  • 原文地址:https://www.cnblogs.com/linlf03/p/14398223.html
Copyright © 2011-2022 走看看