网站首页 > 技术文章 正文
使用链表实现Set
java中的Set集合方法很多,在这里我只实现其中的添加,删除,包含,判空以及获取大小这几种方法。
手写链表具体实现
用链表实现Set集合我们可以用java提供的相关链表来实现,但是为了追本溯源,我们在这里手写数据结构的链表,让大家深入理解
链表完整代码实现:
package Set; /** * Created by lirui on 2018/12/9. */ public class LinkedList<E> { private class Node{ public E e; public Node next; public Node(E e, Node next){ this.e = e; this.next = next; } public Node(E e){ this(e, null); } public Node(){ this(null, null); } @Override public String toString(){ return e.toString(); } } private Node dummyHead; private int size; public LinkedList(){ dummyHead = new Node(); size = 0; } // 获取链表中的元素个数 public int getSize(){ return size; } // 返回链表是否为空 public boolean isEmpty(){ return size == 0; } // 在链表的index(0-based)位置添加新的元素e // 在链表中不是一个常用的操作,练习用:) public void add(int index, E e){ if(index < 0 || index > size) throw new IllegalArgumentException("Add failed. Illegal index."); Node prev = dummyHead; for(int i = 0 ; i < index ; i ++) prev = prev.next; prev.next = new Node(e, prev.next); size ++; } // 在链表头添加新的元素e public void addFirst(E e){ add(0, e); } // 在链表末尾添加新的元素e public void addLast(E e){ add(size, e); } // 获得链表的第index(0-based)个位置的元素 // 在链表中不是一个常用的操作,练习用:) public E get(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("Get failed. Illegal index."); Node cur = dummyHead.next; for(int i = 0 ; i < index ; i ++) cur = cur.next; return cur.e; } // 获得链表的第一个元素 public E getFirst(){ return get(0); } // 获得链表的最后一个元素 public E getLast(){ return get(size - 1); } // 修改链表的第index(0-based)个位置的元素为e // 在链表中不是一个常用的操作,练习用:) public void set(int index, E e){ if(index < 0 || index >= size) throw new IllegalArgumentException("Set failed. Illegal index."); Node cur = dummyHead.next; for(int i = 0 ; i < index ; i ++) cur = cur.next; cur.e = e; } // 查找链表中是否有元素e public boolean contains(E e){ Node cur = dummyHead.next; while(cur != null){ if(cur.e.equals(e)) return true; cur = cur.next; } return false; } // 从链表中删除index(0-based)位置的元素, 返回删除的元素 // 在链表中不是一个常用的操作,练习用:) public E remove(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("Remove failed. Index is illegal."); Node prev = dummyHead; for(int i = 0 ; i < index ; i ++) prev = prev.next; Node retNode = prev.next; prev.next = retNode.next; retNode.next = null; size --; return retNode.e; } // 从链表中删除第一个元素, 返回删除的元素 public E removeFirst(){ return remove(0); } // 从链表中删除最后一个元素, 返回删除的元素 public E removeLast(){ return remove(size - 1); } // 从链表中删除元素e public void removeElement(E e){ Node prev = dummyHead; while(prev.next != null){ if(prev.next.e.equals(e)) break; prev = prev.next; } if(prev.next != null){ Node delNode = prev.next; prev.next = delNode.next; delNode.next = null; size --; } } @Override public String toString(){ StringBuilder res = new StringBuilder(); Node cur = dummyHead.next; while(cur != null){ res.append(cur + "->"); cur = cur.next; } res.append("NULL"); return res.toString(); } }
LinkedListSet集合实现
首先创建一个Set接口
public interface Set<E> { //添加元素,元素去重 void add(E e); //删除元素 void remove(E e); //判断是否包含某个元素 boolean contains(E e); //判断是否为空 boolean isEmpty(); //获取长度 int getSize(); }
创建LinkedListSet类
public class LinkedListSet<E extends Comparable<E>> implements Set<E> { private LinkedList linkedList; public LinkedListSet(){ linkedList=new LinkedList(); } @Override //添加元素,元素不能重复 public void add(E e) { //判断元素是否已经存在 if (!contains(e)){ linkedList.addFirst(e); } } @Override //删除元素 public void remove(E e) { linkedList.removeElement(e); } @Override //判断是否包含某元素 public boolean contains(E e) { return linkedList.contains(e); } //判断集合元素是否为空 @Override public boolean isEmpty() { return linkedList.isEmpty(); } //获取集合元素个数 @Override public int getSize() { return linkedList.getSize(); } }
使用二叉搜索树实现Set集合
二叉搜索树在我之前的文章已经详细为大家实现,这里就不再赘述,如果没有看过我之前的关于二叉搜索树具体实现的朋友可以先根据链接观看后,继续阅读本文章
BstSet具体实现
public interface Set<E> { //添加元素,元素去重 void add(E e); //删除元素 void remove(E e); //判断是否包含某个元素 boolean contains(E e); //判断是否为空 boolean isEmpty(); //获取长度 int getSize(); }
总结
其实懂得了链表和二叉搜索树,要实现Set集合就非常简单,链表和二叉搜索树均能实现Set集合,但其性能是是有差异的,这里通过一张图为大家展现一下这两者的性能比较:
从图中可看出,使用链表的时间复杂度要比使用二叉搜索树要高,但二叉搜索树也会出现时间复杂度为n的情况,那就是当数据是依次递增或者递减的时候,但后期我会讲到平衡二叉树,就会避免这种情况。
欢迎大家评论转发收藏,还没关注的朋友记得关注一下,您的支持就是我不断进步的动力,一起加油
猜你喜欢
- 2024-10-08 java常用数据判空、比较和类型转换
- 2024-10-08 集合框架-ArrayList源码分析(java集合框架源码解析)
- 2024-10-08 大数据编程入门:Java ArrayList(java大数据视频教程)
- 2024-10-08 Python开发入门之列表-List(python列表的基本操作编程)
- 2024-10-08 如何在python各种列表中求最值?(如何在python各种列表中求最值的方法)
- 2024-10-08 List接口常用方法(list接口的常用方法)
- 2024-10-08 Python语法基础(6)集合(python中的集合)
- 2024-10-08 Java初学者学习任务总结「15」(java学习知识点路线)
- 2024-10-08 Sonar代码规范分析(sonar代码扫描规则及解决方案)
- 2024-10-08 最详细集合源码解析之ArrayList集合源码解析
- 1512℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 552℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 503℃MySQL service启动脚本浅析(r12笔记第59天)
- 481℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 479℃启用MySQL查询缓存(mysql8.0查询缓存)
- 459℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 439℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 436℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)