1.基本介绍
(1)链表以节点的方式存储
(2)每个节点包含data域,next域(指向下一个节点)
(3)链表的各个节点不一定是连续存放,如下图
(4)链表分有头节点的链表和无头节点的链表
(5)单链表逻辑结构示意图(带头节点)
2.单链表代码实现(增删改查以及遍历)
(1)分析实现方式
1.遍历:通过一个辅助变量temp的遍历,实现对整个链表的遍历
2.增加节点(插入到尾部或插入到指定位置)
当直接插入到到链表尾部时:将一个要添加的节点加入到链表最后一个节点的next域中
当插入到链表指定位置时:先通过辅助变量temp遍历来找到新添加节点的目的位置,当新节点的位置满足:新节点.next==temp.next时,将新节点放入temp的next域中即temp.next=新节点.next
3.修改:通过遍历找到要修改的节点,再将新的数据赋值给对应的节点
4.删除:首先找到要删除的节点的前一个节点temp,再将temp的next域指向要删除节点的后一个节点:temp.next = temp.next.next(此时被删除的节点不再有引用指向,将被垃圾回收机制回收)
(2)代码
package com.lzz.linkedlist;
public class SingleLinkedListDemo {
public static void main(String[] args) {
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
SingleLinkedList sll = new SingleLinkedList();
sll.addByOrder(hero2);
sll.addByOrder(hero3);
sll.addByOrder(hero1);
sll.addByOrder(hero4);
sll.list();//修改前显示
//sll.addByOrder(hero1);
HeroNode hero5 = new HeroNode(2, "卢某", "麒麟");
System.out.println("修改后-------------------");
sll.update(hero5);
sll.list();//修改后显示
sll.delete(3);
System.out.println("删除后------------------");
sll.list();
}
}
//管理英雄信息
class SingleLinkedList {
//定义头节点,
private HeroNode head = new HeroNode(0, "", "");
public void add(HeroNode heroNode) {
HeroNode temp = head;
while (true) {
if (temp.next == null) {
break;
}
temp = temp.next;
}
//此时temp指向链表最后一个元素,将要插入的数据放到temp之后
temp.next = heroNode;
}
//遍历
public void list() {
if (head.next == null) {
System.out.println("链表为空");
return;
}
HeroNode temp = head.next;
while (true) {
if (temp == null) {
break;
}
System.out.println(temp);
temp = temp.next;
}
}
//插入到指定位置
//按照编号添加
public void addByOrder(HeroNode heroNode) {
HeroNode temp = head;
boolean flag = 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;
}
temp = temp.next;
}
if (flag) {
System.out.printf("已经存在英雄编号为%d的英雄\n", heroNode.no);
} else {
heroNode.next = temp.next;
temp.next = heroNode;
}
}
//修改,只修改内容,不修改no
public void update(HeroNode newHeroNode) {
if (head.next == null) {//链表为空
System.out.println("链表为空");
return;
}
boolean flag = false;
HeroNode temp = head.next;
while (true) {
if (temp == null) {
break;//链表遍历完成
}
if (temp.no == newHeroNode.no) {
//找到对应编号
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
temp.name = newHeroNode.name;
temp.nickname = newHeroNode.nickname;
} else {//未找到
System.out.printf("未找到编号为%d的英雄", newHeroNode.name);
}
}
public void delete(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;
}
if(flag){
temp.next = temp.next.next;
}else{
System.out.printf("想要删除的%d节点不存在\n",no);
}
}
}
//定义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;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
}