Java编程内功之怎么使用单链表
发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,这篇文章将为大家详细讲解有关Java编程内功之怎么使用单链表,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。基本介绍链表是有序的列表,但是它在内存中存储
千家信息网最后更新 2025年01月18日Java编程内功之怎么使用单链表
这篇文章将为大家详细讲解有关Java编程内功之怎么使用单链表,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
基本介绍
链表是有序的列表,但是它在内存中存储如下
鸿蒙官方战略合作共建--HarmonyOS技术社区
链表是以节点的方式来存储.
每个节点包含data域,next域:指向下一个节点.
如图:发现每个链表的各个节点不一定是连续存储
链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定.
单链表介绍
单链表(带头节点)逻辑结构示意图如下
单链表的应用实例
使用带head头的单向链表实现-水浒英雄排行榜管理
package com.structures.linkedlist; public class SingleLinkedListDemo { public static void main(String[] args) { HeroNode heroNode1 = new HeroNode(1, "宋江", "及时雨"); HeroNode heroNode2 = new HeroNode(2, "卢俊义", "玉麒麟"); HeroNode heroNode3 = new HeroNode(3, "吴用", "智多星"); HeroNode heroNode4 = new HeroNode(4, "林冲", "豹子头"); SingleLinkedList singleLinkedList = new SingleLinkedList(); singleLinkedList.add(heroNode3); singleLinkedList.add(heroNode2); singleLinkedList.add(heroNode4); singleLinkedList.add(heroNode1); singleLinkedList.list(); } } //定义SingleLinkedList管理我们的英雄 class SingleLinkedList { //先初始化一个头节点,头节点不能动,将来遍历用 private HeroNode head = new HeroNode(0, "", ""); //添加节点到单向链表 //思路:当不考虑编号的顺序时 //1. 找到当前链表的最后节点 //2. 将最后这个节点的next域指向新的节点 public void add(HeroNode node) { //因为head节点不能动,因此我们需要一个辅助遍历temp HeroNode temp = head; //遍历链表,找到最后 while (temp.next != null) { //找到链表的最后 //如果没有找到temp就后移 temp = temp.next; } temp.next = node; } //显示链表[遍历] public void list() { //判断链表是否为空 if (head.next == null) { System.out.println("链表为空"); } //因为头节点不能动,因此我们需要一个辅助变量来遍历 HeroNode temp = head.next; while (temp != null) { //判断是否到最后 //输出节点的信息 System.out.println(temp); //将temp后移 temp = temp.next; } } } //定义一个HeroNode,每个HeroNode对象就是一个节点 class HeroNode { public int no; public String name; public String nickName; public HeroNode next;//指向下一个节点 //构造器 public HeroNode(int no, String name, String nickName) { this.no = no; this.name = name; this.nickName = nickName; } public HeroNode getNext() { return next; } public void setNext(HeroNode next) { this.next = next; } @Override public String toString() { return "HeroNode{" + "no=" + no + ", name='" + name + '\'' + ", nickName='" + nickName + '\'' + '}'; } } /* HeroNode{no=3, name='吴用', nickName='智多星'} HeroNode{no=2, name='卢俊义', nickName='玉麒麟'} HeroNode{no=4, name='林冲', nickName='豹子头'} HeroNode{no=1, name='宋江', nickName='及时雨'} */
可以看到以上链表的实现方式,在添加英雄时,并未按照英雄的编号进行排序. 下面重新写一个添加方法,实现插入英雄时按编号排序
package com.structures.linkedlist; public class SingleLinkedListDemo { public static void main(String[] args) { HeroNode heroNode1 = new HeroNode(1, "宋江", "及时雨"); HeroNode heroNode2 = new HeroNode(2, "卢俊义", "玉麒麟"); HeroNode heroNode3 = new HeroNode(3, "吴用", "智多星"); HeroNode heroNode4 = new HeroNode(4, "林冲", "豹子头"); SingleLinkedList singleLinkedList = new SingleLinkedList(); singleLinkedList.addByNo(heroNode3); singleLinkedList.addByNo(heroNode2); singleLinkedList.addByNo(heroNode4); singleLinkedList.addByNo(heroNode1); singleLinkedList.list(); } } //定义SingleLinkedList管理我们的英雄 class SingleLinkedList { //先初始化一个头节点,头节点不能动,将来遍历用 private HeroNode head = new HeroNode(0, "", ""); //添加节点到单向链表 //思路:当不考虑编号的顺序时 //1. 找到当前链表的最后节点 //2. 将最后这个节点的next域指向新的节点 public void add(HeroNode node) { //因为head节点不能动,因此我们需要一个辅助遍历temp HeroNode temp = head; //遍历链表,找到最后 while (temp.next != null) { //找到链表的最后 //如果没有找到temp就后移 temp = temp.next; } temp.next = node; } //第二种添加英雄的方式,在添加英雄时,根据排名将英雄插入到指定位置 //如果有这个排名,则添加失败,并给出提示 public void addByNo(HeroNode heroNode) { //因为head节点不能动,因此我们需要一个辅助遍历temp //因为单链表,因此找的temp是位于添加位置的前一个节点,否则加入不了 HeroNode temp = head; boolean flag = false;//标识添加的编号是否存在,默认false while (true) { if (temp.next == null) { break; } if (temp.next.no > heroNode.no) {//位置找到,就在temp的后面插入 break; } else if (temp.next.no == heroNode.no) { //编号已存在 flag = true; break; } temp = temp.next; } if (flag) { System.out.printf("准备插入的英雄的编号 %d 已存在,不能加入\n", heroNode.no); } else { //插入链表temp的后面 heroNode.next = temp.next; temp.next = heroNode; } } //显示链表[遍历] public void list() { //判断链表是否为空 if (head.next == null) { System.out.println("链表为空"); } //因为头节点不能动,因此我们需要一个辅助变量来遍历 HeroNode temp = head.next; while (temp != null) { //判断是否到最后 //输出节点的信息 System.out.println(temp); //将temp后移 temp = temp.next; } } } //定义一个HeroNode,每个HeroNode对象就是一个节点 class HeroNode { public int no; public String name; public String nickName; public HeroNode next;//指向下一个节点 //构造器 public HeroNode(int no, String name, String nickName) { this.no = no; this.name = name; this.nickName = nickName; } public HeroNode getNext() { return next; } public void setNext(HeroNode next) { this.next = next; } @Override public String toString() { return "HeroNode{" + "no=" + no + ", name='" + name + '\'' + ", nickName='" + nickName + '\'' + '}'; } } /* HeroNode{no=1, name='宋江', nickName='及时雨'} HeroNode{no=2, name='卢俊义', nickName='玉麒麟'} HeroNode{no=3, name='吴用', nickName='智多星'} HeroNode{no=4, name='林冲', nickName='豹子头'} */
再次进行完善功能,添加修改节点功能
//修改节点的信息,根据no编号来修改,即编号no不能修改. public void update(HeroNode heroNode) { //判断是否为空 if (head.next == null) { System.out.println("链表为空"); } //找到需要修改的节点,根据no编号 HeroNode temp = head.next; boolean flag = false;//表示节点是否找到 while (true) { if (temp == null) { break; } if (temp.no == heroNode.no) { flag = true; break; } temp = temp.next; } if (flag) { temp.name = heroNode.name; temp.nickName = heroNode.nickName; } else { System.out.printf("没有找到 编号%d 的节点,不能修改\n", heroNode.no); } }
再次进行完善功能,添加删除节点功能
//删除节点 public void remove(HeroNode heroNode) { //判断是否为空 if (head.next == null) { System.out.println("链表为空"); } HeroNode temp = head.next; boolean flag = false;//标识是否找到待删除的点 while (true) { if (temp == null) { break; } if (temp.next.no == heroNode.no) { flag = true; break; } temp = temp.next; } if (flag) { temp.next = temp.next.next; } else { System.out.printf("无法删除 编号%d 的节点,\n", heroNode.no); } }
再次进行完善功能,添加统计单链表的有效节点数功能
/** * 获取单链表的有效节点数,不统计头节点 * @param head 链表的头结点 * @return 有效节点数 */ public static int getLength(HeroNode head) { if (head.next == null) { return 0; } int count = 0; HeroNode temp = head.next; while (temp.next != null) { count++; temp = temp.next; } return count; }
再次进行完善功能,添加查找单链表中的倒数第K个节点功能
/** * 查找单链表的倒数第K个节点[新浪面试题] * 思路: * 1.先把链表从头到尾遍历,得到链表的总长度 * 2.得到size后,从链表的第一个开始遍历到(size-index)个,就可以得到 * * @param head * @param index 表示倒数第index个节点 * @return */ public static HeroNode findLastIndexNode(HeroNode head, int index) { if (head.next == null) { return null; } int size = getLength(head); if (index <= 0 || index > size) { return null; } HeroNode temp = head.next; for (int i = 0; i < (size - index); i++) { temp = temp.next; } return temp; }
再次进行完善功能,添加单链表反转功能
/** * 反转链表[腾讯面试题] * 思路: * 1.先定义一个reverseHead = new HeroHead(); * 2.从头到尾遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表的最前端; * 3.原来的链表的head.next = reverseHead.next; */ public static void reverseList(HeroNode head) { if (head.next == null || head.next.next == null) { return; } HeroNode curr = head.next; HeroNode next = null;//指向当前节点[curr]的下一个节点 HeroNode reverseHead = new HeroNode(0, "", ""); while (curr != null) { next = curr.next;//先暂时保存curr节点的下一个节点 curr.next = reverseHead.next;//将curr的下一个节点指向新的链表的最前端 reverseHead.next = curr;//将curr连接到新的链表上 curr = next;//让curr后移 } head.next = reverseHead.next; }
再次进行完善功能,添加从尾到头打印单链表功能
/** * 使用栈的方式逆序打印[百度面试题] */ public static void reversePrint(HeroNode head) { if (head.next == null) { return; } StackheroNodes = new Stack (); HeroNode temp = head.next; while (temp != null) { heroNodes.add(temp); temp = temp.next; } while (heroNodes.size() > 0) { System.out.println(heroNodes.pop()); } }
关于Java编程内功之怎么使用单链表就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
节点
功能
英雄
能动
指向
再次
后移
辅助
及时雨
思路
方式
智多星
豹子
宋江
林冲
玉麒麟
有效
位置
信息
单向
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
普通网络安全认证
操作系统没有数据库怎么设置
天融信服务器安全加固
银河证券的服务器怎么样
数据库中需要多列相加
软件开发部分多少组
成都软件开发贵吗
南充软件开发参考价
软件开发需要掌握什么语言
台州学软件开发总结
石家庄数据库工程师工资高吗
计算机网络技术是什么的产物
e-r数据库练习题
软件开发 询价公告
pop3的服务器地址
网络安全例案
杭州季万网络技术有限公司
浙江华为服务器维修价格
服务器怎么买最安全
郑州软件开发怎样快速
软件开发就是程序代码
新乡网络技术哪个好
网络安全专题教育培训简报
网络技术主管任职资格
三国杀服务器怎么登陆
网络安全保卫人员培训试题
云数据库_id定义类型
海南定制软件开发服务商
黄浦区新能源软件开发项目信息
软件开发周期缺陷趋势图