java -数据结构,单向链表
创始人
2024-03-08 16:04:53
0

顺序表的问题及思考:

  1. 顺序表中间/头部的插入删除,时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间

思考: 如何解决以上问题呢?下面给出了链表的结构来看看

一、链表

1.1、链表的概念及结构

链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的
在这里插入图片描述

在这里插入图片描述

1.1.1、创建一个类表示节点 - ListNode

//NodeList 表示节点 类
class ListNode{//值域public int val;//下一个节点的地址public ListNode next;public ListNode(int val){this.val = val;}
}

在这里插入图片描述

1.1.2、创建一个类来表示链表 - MyLinkedList

//ListNode 表示节点 类
class ListNode{//值域public int val;//下一个节点的地址public ListNode next;public ListNode(int val){this.val = val;}
}public class MyLinkedList {public static void main(String[] args) {//当new 一个节点的时候就是创建一个节点,值为 1ListNode nodeList = new ListNode(1);}
}

new 一个节点

如和创建多个节点,让这些节点串起来

首先要有一个头结点

单向,带头,不循环的单链表
在这里插入图片描述

理解链表中: 带头、不带头、单向、双向、循环、不循环的意思

带头 和 不带头

在这里插入图片描述

循环 和 不循环

在这里插入图片描述

单向 和 双向

在这里插入图片描述

1.1.3、模拟实现 单向 不带头 非循环的链表

在这里插入图片描述

用过列举的方式,创建几个节点,然后将他们连接起来

//ListNode 表示节点 类
class ListNode{//值域public int val;//下一个节点的地址public ListNode next;public ListNode(int val){this.val = val;}
}public class MyLinkedList {public ListNode head;//创建5个节点的链表public void creatList(){//当new 一个节点的时候就是创建一个节点,值为 1ListNode ListNode1 = new ListNode(10);ListNode ListNode2 = new ListNode(20);ListNode ListNode3 = new ListNode(30);ListNode ListNode4 = new ListNode(40);ListNode ListNode5 = new ListNode(50);ListNode1.next = ListNode2;ListNode2.next = ListNode3;ListNode3.next = ListNode4;ListNode4.next = ListNode5;this.head = ListNode1;}
}

在这里插入图片描述
此时就有5个节点了

1.1.4、遍历链表数据

首先,我要区分清楚,链表 不是顺序表,不是一块连续的空间。 链表的每个元素 是由地址来连接起来的。
也就是说 我们不能使用普通思维模式 去思考 遍历链表的数据域的值

既然 链表是靠地址联系起来的,也就是说 靠 next域中 存储的地址来联系个节点的数据,
这就是我们突破点。
利用 head 遍历每个每个节点的数据 写法 head = head.next,你可以参考上面的图,来细品。
这样我们就跳转到下一个节点,算了我还是画个图,请看下图

//打印链表的数据public void disPlay(){ListNode cur = this.head;while(cur != null){System.out.print(cur.val + " " );cur = cur.next;}System.out.println();}

在这里插入图片描述

测试一下:

public class TestDome {public static void main(String[] args) {MyLinkedList myLinkedList = new MyLinkedList();myLinkedList.creatList();myLinkedList.disPlay();}
}

.2.1、

1.2、链表里面的操作

1.2.1、得到单链表的长度

//得到单链表的长度public int size(){int usedSize = 0;ListNode cur = this.head;while(cur != null){cur = cur.next;usedSize++;}return usedSize;};

1.2.2、头插法

//头插法public void addFirst(int data){ListNode node = new ListNode(data);node.next = head;head = node;};

在这里插入图片描述

1.2.3、尾插法

//尾插法public void addLast(int data){ListNode node = new ListNode(data);ListNode cur = this.head;//判断链表是否为空if(this.head == null){this.head = node;} else{while(cur.next != null){cur = cur.next;}cur.next = node;}};

在这里插入图片描述

1.2.4、查找是否包含关键字key是否在单链表当中

//查找是否包含关键字key是否在单链表当中//查找是否包含关键字key是否在单链表当中public boolean contains(int key){ListNode cur = head;while(cur != null){if(cur.val == key){return true;}cur = cur.next;}return false;};

为

1.2.5、任意位置插入,第一个数据节点为0号下标

/任意位置插入,第一个数据节点为0号下标public void addIndex(int index,int data){ListNode node = new ListNode(data);if(index < 0 || index > size()){System.out.println("index 位置不合法!");return;}if(index == 0){addFirst(data);return;}if(index == size()){addLast(data);return;}//中间位置ListNode cur = this.head;while(index - 1 != 0){cur = cur.next;index--;}node.next = cur.next;cur.next = node;};

在这里插入图片描述

1.2.6、删除第一次出现关键字为key的节点

//删除第一次出现关键字为key的节点public void remove(int key){//当链表为空的时候if(size() == 0){System.out.println("删除失败,链表为空!");return;}//当删除的是头节点的时候if(this.head.val == key){this.head = this.head.next;return;}ListNode cur = this.head;while(cur.next != null){if(cur.next.val == key){cur.next = cur.next.next;return;}cur = cur.next;}return;};

在这里插入图片描述

1.2.7、删除所有值为key的节点

 //删除所有值为key的节点public void removeAllKey(int key){if(this.head == null){System.out.println("链表为空!");return;}//cur.val 就是删除的值ListNode prev = this.head;ListNode cur = this.head.next;while (cur != null){if(cur.val == key){prev.next = cur.next;cur = cur.next;}else{prev = cur;cur = cur.next;}}//删除头结点if(head.val == key){this.head = head.next;}};

在这里插入图片描述

1.2.8、清除单链表

清除链表里面的数据的时候,最好是一个节点一个节点的释放(置为null)

//清除单链表public void clear(){//粗暴的做法//this.head = null;while (this.head != null){ListNode curNext = this.head;this.head = null;head = curNext;}};

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...