链表 (Linked List)
Posted lililixuefei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表 (Linked List)相关的知识,希望对你有一定的参考价值。
链表介绍:
-
链表是以节点的方式来储存,是链式存储;
-
每个节点包含 data 域,next 域:指向下一个结点;
-
链表的各个节点不一定是连续存储的;
-
链表分为带头结点链表 和 没有头结点的链表,根据实际需求来确定;
单链表的应用实例:
使用带 head 头的单向链表实现 ---水浒英雄排行榜管理完成对英雄人物的增删改查操作;
-
第一种方法在添加英雄时,直接添加到链表的尾部
-
第二种方式在添加英雄时,根据排名将英雄插入到指定位置(如果有这个排名,则添加失败,并给出提示):
-
修改节点功能
思路:(1)先找到该节点,通过遍历(2)temp.name = newHeroNode.name;temp.nickname= newHeroNode.nickname;
-
删除节点
package dataStructures.linkedList; ? ? /** * @author : 雪飞oubai * @date : 2020/4/1 10:20 */ public class SingleLinkedListDemo { public static void main(String[] args) { HeroNode heroNode1 = new HeroNode(1, "xuefei1", "oubai1"); HeroNode heroNode3 = new HeroNode(3, "xuefei3", "oubai3"); HeroNode heroNode2 = new HeroNode(2, "xuefei2", "oubai2"); HeroNode heroNode5 = new HeroNode(5, "xuefei5", "oubai5"); HeroNode heroNode4 = new HeroNode(4, "xuefei4", "oubai4"); SingleLinkedList singleLinkedList = new SingleLinkedList(); singleLinkedList.addByOrder(heroNode1); singleLinkedList.addByOrder(heroNode3); singleLinkedList.addByOrder(heroNode2); singleLinkedList.addByOrder(heroNode5); singleLinkedList.addByOrder(heroNode4); // singleLinkedList.list(); HeroNode heroNode6 = new HeroNode(4, "xuefei188", "oubai4"); singleLinkedList.updateHeroNode(heroNode6); singleLinkedList.del(5); singleLinkedList.list(); ? } } ? // 定义SingleLinkedList 管理我们的英雄 class SingleLinkedList { // 先初始化一个头结点,头结点不动,不存放具体数据 private HeroNode head = new HeroNode(0, "", ""); ? // 添加节点到链尾 public void add(HeroNode heroNode) { // 定义一个辅助变量 HeroNode temp = head; while (temp.next != null) { temp = temp.next; } temp.next = heroNode; } ? // 按英雄编号顺序添加 public void addByOrder(HeroNode heroNode) { // 定义一个辅助变量 HeroNode temp = head; boolean flag = false; while (true) { if (temp.next == null) { // 说明 temp 已经在链表最后了 break; } if (temp.next.no > heroNode.no) { // 位置找到了,就在temp后面插入 break; } else if (temp.next.no == heroNode.no) { // 说明希望添加的节点的编号已经存在了 flag = true; break; } temp = temp.next; } // 判断 flag 的值 if (flag) { System.out.printf("准备插入的英雄编号已经存在了,不能加入 ", heroNode.no); } else { // 插入到链表中 temp 的后面 heroNode.next = temp.next; temp.next = heroNode; } } ? // 根据英雄编号修改 英雄信息 ,编号不变 public void updateHeroNode(HeroNode heroNode) { // 定义一个辅助变量 HeroNode temp = head.next; boolean flag = false; while (true) { if (temp == null) { break; } if (temp.no == heroNode.no && (Integer) heroNode.no != null) { // 找到 flag = true; break; } temp = temp.next; } if (flag) { temp.name = heroNode.name; temp.nickName = heroNode.nickName; } else { System.out.println("无对应编号的英雄!"); } } // 删除对应编号英雄 public void del(int no) { HeroNode temp = head; boolean flag = false; //标志是否找到待删除节点 while (true) { if (temp.next == null) { break; } if (temp.next.no == no) { // 找到待删除节点的前一个节点 flag = true; break; } temp = temp.next; // temp后移 } if (flag) { temp.next = temp.next.next; } else { System.out.println("要删除的节点不存在"); } } ? // 遍历整个链表 public void list() { // 先判断链表是否为空 if (head.next == null) { throw new RuntimeException("链表为空"); } // 因为头结点不能动,因此我们需要一个辅助变量来遍历 HeroNode temp = head.next; while (temp != null) { System.out.println(temp); temp = temp.next; } } } ? class HeroNode { int no; String name; String nickName; HeroNode next; // 指向下一个节点 ? // 构造器 public HeroNode(int no, String name, String nickName) { this.no = no; this.name = name; this.nickName = nickName; } ? @Override public String toString() { return "HeroNode{" + "no=" + no + ", name=‘" + name + ‘‘‘ + ", nickName=‘" + nickName + ‘‘‘ + ‘}‘; } }
单链表面试题
-
求单链表中有效节点的个数
// 获得单链表的节点的个数(如果是带头结点的,需求不统计头结点) /** * @param head 链表的头结点 * @return 返回值就是有效节点的个数 */ public static int getLength(HeroNode head){ if(head.next == null){ return 0; } int length = 0; // 定义一个辅助变量 HeroNode cur = head.next; while(cur != null){ length++; cur = cur.next; } return length; }
-
查找单链表中倒数第 k 个节点
// 查找单链表中的倒数第K个节点 public static HeroNode findLastIndexNode(HeroNode head, int index) { // 判断如果链表为空,返回 null if (head.next == null) { return null; //没有找到 } // 第一个遍历得到链表的长度(节点个数) int size = getLength(head); if (size <= 0 || index > size) { return null; } // 定义辅助变量,for循环定位倒数的index HeroNode cur = head.next; for (int i = 0; i < size - index; i++) { cur = cur.next; } return cur; }
以上是关于链表 (Linked List)的主要内容,如果未能解决你的问题,请参考以下文章
[leetcode]141. Linked List Cycle判断链表是否有环
LeetCode2.Linked List — Linked List Cycle II 链表环2