java学习笔记(7)--链表
标签(空格分隔):笔记
java其实已经将很多底层的数据结构进行了封装,虽然工作用不到,但是笔试和面试问的还是比较频繁的,而且这种面试题还是直接手撕代码,故专门总结一下。
1. 概念###
1.1 链表(Linked list)
是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。
1.2 单向链表(Single-Linked List)
- 单链表是链表中结构最简单的。一个单链表的节点(Node)分为两个部分,第一个部分(data)保存或者显示关于节点的信息,另一个部分存储下一个节点的地址。最后一个节点存储地址的部分指向空值。
- 单向链表只可向一个方向遍历,一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。而插入一个节点,对于单向链表,我们只提供在链表头插入,只需要将当前插入的节点设置为头节点,next指向原头节点即可。删除一个节点,我们将该节点的上一个节点的next指向该节点的下一个节点。
2. 链表的java实现###
2.1 设计一个接口,定义链表需要哪些操作(已通过验证,放心用)
public interface ILinkedList {
//添加元素
boolean addItems(Object obj);
//删除元素
boolean deleteItems(Object obj);
//删除头元素
boolean deleteheadItems();
//查找
Object findItems(Object obj);
//返回长度
int length();
//展示所有元素
void display();
//判断是否为空
boolean isEmpty();
}
2.2 定义一个单链表,实现上述接口的操作(已通过验证,放心使用)
public class NewSingleList implements ILinkedList{
private int size;//链表长度
private Node head;//链表的头结点,因为是成员变量,默认为null
//
//定义一个成员内部类Node,包含头部数据和next指向的对象
public class Node{
private Object data;
private Node next;
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
}
//添加
@Override
public boolean addItems(Object obj) {
Node n1=new Node(obj,null);
if(isEmpty()) {
head=n1;
size++;
return true;
}
else {
n1.next=head;//头插法,从头部插入,新插入的节点作为新的head
head=n1;
size++;
return false;
}
}
//删除元素
@Override
public boolean deleteItems(Object obj) {
if(isEmpty()) {
return false;
}
if(head.data.equals(obj)) {
deleteheadItems();//调用删除头部元素的函数
return true;
}
//定义当前节点的前一个节点(初始的时候下面两个起点相同,但是循环一遍之后位置就变了,可以自己试试)
Node previous=head;
Node current=head;//定义当前节点
while(current!=null) {
if(current.data.equals(obj)) {
previous.next=current.next;//删除核心代码
size--;
return true;
}
else {
previous=current;
current=current.next;
}
}
return false;
}
//删除头部元素
@Override
public boolean deleteheadItems() {
if(isEmpty()) {
return false;
}
else {
head=head.next;
size--;
return true;
}
}
//查找
@Override
public Object findItems(Object obj) {
if(isEmpty()) {return false;}
Node tmp=head;
while(tmp!=null) {
if(tmp.data.equals(obj)) {return true;}
else {
tmp=tmp.next;
}
}
return false;
}
//返回链表长度
@Override
public int length() {
return size;
}
//展示元素
@Override
public void display() {
Node tmp=head;
while(tmp!=null) {
System.out.println(tmp.data);
tmp=tmp.next;
}
}
//判断是否为空
@Override
public boolean isEmpty() {
if(size==0) {
return true;
}
return false;
}
}
2.3 对这个链表进行测试(已通过验证,放心使用)
public class ListTest01 {
public static void main(String[] args) {
NewSingleList l1=new NewSingleList();
l1.addItems(4);
l1.addItems(7);
l1.addItems(66);
l1.addItems(233);
l1.deleteItems(4);
l1.display();
}
}
3. 链表的常见面试题###
3.1 判断链表是否有环
//点击上述题目链接去LeetCode刷题。第141题
//方法一:双指针,只要有环,快的指针总会赶上慢的指针,空间复杂度O(1)
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null || head.next==null){
return false;
}
ListNode l1=head;
ListNode l2=head.next;
while(l1 !=null && l2 !=null && l2.next!=null){
if(l1==l2){
return true;
}
l1=l1.next;
l2=l2.next.next;
}
return false;
}
}
//如果需要让你用一个指针,检查一个结点此前是否被访问过来判断链表是否为环形链表。常用的方法是使用哈希表。时间和空间复杂度都是O(n)
public class Solution {
public boolean hasCycle(ListNode head) {
Set<ListNode> l1=new HashSet<>();
while(head != null){
if(l1.contains(head)){
return true;
}
else{
l1.add(head);
}
head=head.next;
}
return false;
}
}
3.2 找出链表交点
//链表的交点难点在于链表的长度不同,当同时进行移位的时候,由于长度不同,可能会导致相同的点完美错过
//例如两个链表,一个是1-2-5-7-8-1,一个是4-3-8-1,
//当这两个同时从头开始时,如果list1=list1.next;list2=liat2.next;当list2指向8的时候,list1刚指向5,显然不行。
//但是如果把两个拼接起来,二者等长,变成1-2-5-7-8-1-4-3-8-1和 4-3-8-1-1-2-5-7-8-1那就容易多了
// 1-2-5-7-\ /-1-2-5-7-8
// 8-1-
// 4-3-/ \4-3-8
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode l1 = headA, l2 = headB;
while (l1 != l2) {
l1 = (l1 == null) ? headB : l1.next;
l2 = (l2 == null) ? headA : l2.next;
}
return l1;
}
}
3.3 链表翻转
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev=null;
ListNode cur=head;
while(cur !=null){
ListNode nextTemp = cur.next;
cur.next = prev;
prev = cur;
cur = nextTemp;
}
return prev;
}
}
java学习笔记(7)--链表的更多相关文章
- java学习笔记——可用链表
NO 链表方法名称 描述 1 public void add(数据类型 对象) 向链表中增加数据 2 public int size() 查看链表中数据个数 3 public boolean isEm ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- 0035 Java学习笔记-注解
什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...
- Java学习笔记(04)
Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...
- 0032 Java学习笔记-类加载机制-初步
JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...
- 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用
垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...
- 0028 Java学习笔记-面向对象-Lambda表达式
匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...
- 0025 Java学习笔记-面向对象-final修饰符、不可变类
final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...
- Java学习笔记-多线程-创建线程的方式
创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...
随机推荐
- 微信小程序微信登录
开发接口 登录 wx.login wx.checkSession 签名加密 小程序登录 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系. 登录流程时序 ...
- vxlan和macvlan操作
vxlan: 192.168.1.112 ———— 192.168.1.108 —— 192.168.1.109192.168.1.112配置:docker run -d -p 8500:8500 - ...
- Kali Linux硬盘扩容
传送门--->http://www.kali.org.cn/thread-27079-1-1.html.kali虚拟机扩容
- SQL查询练习题
1.查询学生"百里守约"的基本信息 select * from students where name='百里守约' 2.查询学生百里守约"或"百里玄策&quo ...
- centos6安装vim插件youcompleteme问题及解决
首先clone vim8代码库 git clone https://github.com/vim/vim.git 然后编译 注意下自己的python2.7config在哪儿 ./configure - ...
- 查看 systemctl 崩溃日志 及 运行日志
vi /var/log/syslog 查看指定服务的: grep "bx" /var/log/syslog
- rg.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
原先跑TEST CASE的时候没有出错 但是跑到整个程序里面,除了这个问题, 网上也找了下资料,说是用merge之类的可以解决,因为你这个update的obj和session里面的不用,所以导致此问题 ...
- oracle/mysql经典电子书籍pdf下载
Oracle LZ写的书,深入结合oracle设计.优化/SQL优化.应用层架构与优化.大量生产案例,敬请期待... Oracle编程艺术 深入理解数据库体系结构(第3版) 链接:https://pa ...
- vue报错:There are multiple modules with names that only differ in casing.
今天写项目时,遇到报错信息如下: 经过多次排除及参考网上文章,最后找到问题所在 排查原因:1 .在引用组件时,路径大小写不对也会造成此报错,看例子:错误写法: 正确写法: 2.在组件使用vuex时,引 ...
- Apache-dbutils 简介及事务处理
一:commons-dbutils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化 ...