【数据结构】链表(1)

server/2024/10/18 18:21:11/

【概念】

一种物理存储结构上的非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序来实现的

也就是说,链表是由一个一个的节点组织起来的,如车厢一般,整体就叫做链表

链表结构】

节点可以理解为”节点对象“,它有两个域,一个val域,用于存储数据,一个next域,用于存储下一个节点的地址

【单向,不带头,非循环链表

一般定义一个"head"对象作为链表的头节点

这是最常见的链表类型

【单向,带头,非循环链表

head这个节点可以认为是一个标志,其val域存储的值不具备实际意义

【单向,带/不带头,循环链表

链表的实现】

链表由若干节点构成,这个节点又是一个完整的结构,那么就可以把节点定义为一个”内部类”

public class MySingleLinkedList
{class ListNode // 这就是一个内部类{public int val;public ListNode next; // next域中存放节点的地址,因此next的数据类型是ListNodepublic ListNode(int val) //构造方法{this.val = val;}}public ListNode head;//代表链表的头节点public void createList(){ListNode node1 = new ListNode(12);ListNode node2 = new ListNode(23);ListNode node3 = new ListNode(34);ListNode node4 = new ListNode(45);ListNode node5 = new ListNode(56);}
}

我们需要让第一个节点和第二个节点之间关联,以此类推

因此使用该代码

通过node1去访问next域,而node2这个引用,引用的是一个完整对象,node2中存放的就是这个对象的地址“0x35”,所以node1中的next域的值被修改为了0x35

所以我们认为,它的指向关系已经有了

因此可写出如下代码

 public void createList(){ListNode node1 = new ListNode(12);ListNode node2 = new ListNode(23);ListNode node3 = new ListNode(34);ListNode node4 = new ListNode(45);ListNode node5 = new ListNode(56);node1.next = node2;node2.next = node3;node3.next = node4;node4.next = node5;this.head = node1;//将node1视为头节点}

【遍历每个节点的值,并打印】

public void display()//遍历每个节点的值并打印{ListNode cur = head;//定义cur,让cur遍历,若让head遍历那只能遍历一次,head无法回归最开始的位置while(cur != null){System.out.println(cur.val + " ");cur = cur.next;}System.out.println();}

 【计算链表大小】

 public int size()//计算链表大小{int count = 0;ListNode cur = head;while(cur != null){count++;cur = cur.next;}return count;}

 【头插法】

 头插法要修改两个地方,第一个是新节点的next域,第二个是head的指向

需要使用这两行代码

 public void addFirst(int val){ListNode node = new ListNode(val);node.next = head;head = node;}

这两行代码的顺序不可改变,如果首先执行head=node,那么node.next=head会变成:

它自己指向了自己,后面的节点丢了

总结:插入节点时一般首先绑后边

 【尾插法】

首先找到链表的尾巴(cur一直遍历,当cur.next==null时,cur指向了尾巴),然后让cur的next域的值被设置为node的地址(cur.next = node)

 public void addLast(int val){ListNode node = new ListNode(val);if(head == null) //整个是空链表时,直接插即可{head = node;return;}ListNode cur = head;while(cur.next != null){cur = cur.next;}cur.next = node;}

 【任意位置插入】

 

1.让cur走index-1步,找到要插入的前一个位置

2.“node的next域”被设置为“cur的next域中所存放的地址”(node.next = cur.next)

3.cur的next域被设置为node的地址(cur.next = node)

当index为0,使用头插法,index等于最大长度,使用尾插法,index不合法,抛异常

public void addLast(int val){ListNode node = new ListNode(val);if(head == null) //整个是空链表时,直接插即可{head = node;return;}ListNode cur = head;while(cur.next != null){cur = cur.next;}cur.next = node;}public  void addIndex(int index, int val){//1.判断index的合法性try {checkIndex(index);} catch (InterruptedException e) {e.printStackTrace();}//2.index == 0 || index == size()if(index == 0){addFirst(val);return;}if(index == size()){addLast(val);return;}//3.找到index的前一个位置ListNode cur = findIndexSubOne(index);//4.进行链接ListNode node = new ListNode(val);node.next = cur.next;cur.next = node;}private ListNode findIndexSubOne(int index)//找到index - 1位置{int count = 0;ListNode cur = head;if(count != index - 1){cur = cur.next;count++;}return cur;}private void checkIndex(int index) throws InterruptedException//检查index是否合法{if(index < 0 || index > size()){throw new IndexNotLegalException("index不合法");}}
}
public class IndexNotLegalException extends RuntimeException
{public IndexNotLegalException(){}public IndexNotLegalException(String msg){super(msg);}
}
public class IndexNotLegalException extends RuntimeException
{public IndexNotLegalException(){}public IndexNotLegalException(String msg){super(msg);}
}

 【删除第一次出现关键字为key的节点】

设关键字key为34

1.先找到34的前一个,cur

当cur的next域中所存放地址节点的val域值与关键字相等时,成功找到(cur.next.val = val)

2.找到cur后,定义cur的下一个节点del(ListNode del = cur.next),随后进行删除,cur的next域被设置为del的next域中所存放的地址(cur.next = del.next)

或者不去定义del,将cur的next域设置为cur下一个节点的next域所存放的地址(cur,next = cur.next.next)

 public void remove(int val){//1.找到需要删除的关键字的前一个ListNode cur = head;while(cur.next != null){if(cur.next.val == val){ListNode del = cur.next;cur.next = del.next;return;}cur = cur.next;}}

 【删除所有关键字key】

设要删除的key为45

1.定义两个节点,cur代表当前需要删除的节点,prev代表当前需要删除节点cur的前驱节点

2.

当cur的val域和要删除的key相符时

将prev的next域设置为cur的next域中存放的地址(prev.next = cur.next),随后让cur继续往后走(cur = cur.next)

当cur的val域和要删除的key不相符时

prev指向cur(prev = cur)(或者prev指向prev的next域中存放的地址(prev = prev.next))

随后让cur继续往后走(cur = cur.next)

3.如果head的值和要删除的val相符,让headr往后走(head = head.next)

 public void removeAllKey(int val){//1,判空if(head == null){return;}//2.定义prev和curListNode prev = head;ListNode cur = head.next;//3.开始判断并删除while(cur != null){if(cur.val == val){prev.next = cur.next;cur = cur.next;}else{prev = cur; //prev = prev.next;cur = cur.next;}}//4.处理头节点if(head.val == val){head = head.next;}}

 【清空链表

  public void clear(){ListNode cur = head;while(cur != null){ListNode curN = cur.next;cur.next = null;cur = curN;}head = null;}


http://www.ppmy.cn/server/128138.html

相关文章

软考数据库部分 ---- (概念数据库模型,三级模式,两级映像,事物管理)

文章目录 一、概念数据库模型二、结构数据库模型三、三级模式四、两级映像五、关系模式基本术语六、关系模式七、关系的数学定义八、数据定义语言九、SQL访问控制十、视图十一、索引十二、关系模式十三、范式十四、数据库设计十五、事物管理&#xff08;ACID&#xff09;十六、…

【Python游戏开发】贪吃蛇游戏demo拓展

拓展上一项目【Python游戏开发】贪吃蛇 实现穿墙效果 # 检测游戏是否结束 def check_gameover():global finished# 移除蛇头位置超过窗口判断for n in range(len(body) - 1):if(body[n].x snake_head.x and body[n].y snake_head.y):finished True # 状态检测 def ch…

M3u8视频由手机拷贝到电脑之后,通过potplayer播放报错找不到文件地址怎么解决?

该文章前面三节主要介绍M3u8视频是什么&#xff0c;视频播放错误(找不到地址)的解决方法在后面 M3U8是一种多媒体播放列表文件格式&#xff0c;主要用于流媒体播放。 一、文件格式特点 1. 文本文件&#xff1a;M3U8是一个采用 UTF-8 编码的文本文件&#xff0c;这意味着它可…

使用 Python 遍历文件夹

要解决这个问题&#xff0c;使用 Python 的标准库可以很好地完成。我们要做的是遍历目录树&#xff0c;找到所有的 text 文件&#xff0c;读取内容&#xff0c;处理空行和空格&#xff0c;并将处理后的内容合并到一个新的文件中。 整体思路&#xff1a; 遍历子目录&#xff1…

尝试从 http://pypi.doubanio.com/simple 这个索引源安装 webdriver 时出现了问题

问题如下&#xff1a; WARNING: The repository located at pypi.doubanio.com is not a trusted or secure host and is being ignored. If this repository is available via HTTPS we recommend you use HTTPS instead, otherwise you may silence this warning and allow …

学习资料库系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;观看记录管理&#xff0c;基础数据管理&#xff0c;论坛信息管理&#xff0c;公告信息管理&#xff0c;轮播图信息 微信端账号功能包括&#xff1a;系统首页&#xff0c;阅读资…

基于拥堵模型的轻量级平台公交室内情况监控系统

论文标题&#xff1a;Bus Indoor Situation Monitoring System Based on Congestion Model Using Lightweight Platform 作者信息&#xff1a;Dong Hyun Kim, Yun Seob Kim, 和 Jong Deok Kim* 所属机构&#xff1a;Pusan National University, Department of Computer Scienc…

Linux中环境变量

基本概念 环境变量Environmental variables一般是指在操作系统中用来指定操作系统运行环境一些参数。 我们在编写C、C代码时候&#xff0c;在链接的时候从来不知道我们所链接的动态、静态库在哪里。但是还是照样可以链接成功。生成可执行程序。原因就是相关环境变量帮助编译器…