慕课网liuyubobobo老师课程学习笔记---part6:集合与映射

本文介绍了集合与映射在数据结构中的应用,特别是通过二分搜索树和链表实现的集合。文章讨论了不同实现方式的性能差异,如LinkedListSet与BSTSet的时间复杂度对比,并提供了LeetCode相关问题的解决方案,如804题的唯一摩尔斯密码词和349、350题的交集问题,强调了集合与映射在处理重复元素时的角色。
摘要由CSDN通过智能技术生成

1、集合基础以及基于二分搜索树的集合实现
  集合与映射(Set and Map)是高层的数据结构,什么是高层的数据结构?例如之前的 栈、队列,这些数据结构的底层实现可以是多种多样的,可以是动态数组,也可以是链表,这样的数据结构就是高层的数据结构。

目前为止:
底层的数据结构:数组、链表、二分搜索树
高层的数据结构:栈、队列、集合与映射

在这里插入图片描述
  二分搜索树实现集合(很简单,直接使用二分搜索树的方法即可)

package com.lkj;

/**
 * 使用二分搜索树实现集合
 * FileOperationFileOperation注意,集合中不能包含重复的元素!
 */
public class BSTSet<E extends Comparable<E>> implements Set<E>
{
   
    private BinarySearchTree<E> bst;
    public BSTSet()
    {
   
        bst = new BinarySearchTree<E>();
    }


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

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

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

2、基于链表的集合实现
在这里插入图片描述
  代码如下:(其实也就是调用链表的方法,稍微改造一下,很简单)

public class LinkedListSet<E> implements Set<E>
{
   
    private LinkedList<E> list;
    public LinkedListSet()
    {
   
        list = new LinkedList<>();
    }

    @Override
    public void add(E e)
    {
   //链表添加之前,需要先判断这个元素是否存在,不存在则进行添加(set中不能有重复的元素)
        if(!list.contains(e))
            list.addFirst(e);//链表的addFirst()方法的时间复杂度是 O(1)
    }

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

    @Override
    public void remove(E e)
    {
   
        //删除链表中元素为e的结点。链表的remove方法是删除index位置的结点。
        list.removeElement(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<>();
        if(FileOperation.readFile("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());
        }

        System.out.println();


        System.out.println("A Tale of Two Cities");

        ArrayList<String> words2 = new ArrayList<>();
        if(FileOperation.readFile("a-tale-of-two-cities.txt", words2)){
   
            System.out.println("Total words: " + words2.size());

            LinkedListSet<String> set2 = new LinkedListSet<>();
            for(String word: words2)
                set2.add(word);
            System.out.println("Total different words: " + set2.getSize());
        }
    }
}

3、集合类的复杂度分析
  测试 LinkedListSet 与 BSTSet 的性能差异,我们发现保存相同的单词, LinkedListSet 所耗费的时间比 BSTSet 高出一个数量级。
  可以看出,二分搜索树 add() 、remove()、contains() 操作的时间复杂度都是 O(logn)级别的。
在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值