单链表
1.简单介绍
(1)单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
(2)链表的各个节点不一定是连续存储
(3)链表分为带头结点的链表和不带头结点的链表,在实际中根据需求来确定
2.单链表的应用实例
使用带 head 头的单向链表实现 –水浒英雄排行榜管理完成对英雄人物的增删改查操作
注:在执行添加操作时,是根据排名进行添加的,而不是直接在尾部进行添加
3.思路分析(具体细节见代码)
添加:
(1)创建临时变量temp,借助temp遍历单链表
(2)找到要添加元素的前一个位置,执行 heroNode.next=temp.next; temp.next=heroNode;
删除:
(1)创建临时变量temp,借助temp遍历单链表
(2)找到要删除元素的前一个位置,执行 temp.next=temp.next.next;
更新:
(1)创建临时变量temp,借助temp遍历单链表
(2)找到该元素所在位置,对其进行更改
4.代码实现
package cn.zzw.algorithm.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 list=new SingleLinkedList();
//添加英雄
list.add(hero2);
list.add(hero1);
list.add(hero4);
list.add(hero3);
System.out.println("更改英雄之前的链表");
list.show();
//更改英雄内容
HeroNode newHeroNode=new HeroNode(3,"有用","小智");
list.update(newHeroNode);
System.out.println("更改英雄之后的链表");
list.show();
//显示链表元素
System.out.println("删除英雄之前的链表");
list.show();
//删除英雄
list.delete(1);
System.out.println("删除英雄之后的链表");
list.show();
}
}
//定义HeroNode,每个HeroNode对象就是一个英雄对象
class HeroNode
{
public int no;
public String name;
public String nikename;
public HeroNode next;//指向下一个结点
public HeroNode(int no,String name,String nikename)
{
this.no=no;
this.name=name;
this.nikename=nikename;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nikename='" + nikename + '\'' +
'}';
}
}
//定义SingleLinkedList
class SingleLinkedList
{
//初始化头结点,不存放具体数据
private HeroNode head=new HeroNode(0,"","");
//根据英雄的no号的大小进行添加
public void add(HeroNode heroNode)
{
//头结点不能动,需要借助一个辅助变量temp来遍历链表
HeroNode temp=head;
//标志当前链表中是否有该英雄,若有,则返回true,并不能再进行插入
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;//说明该英雄已经存在
break;
}
temp=temp.next;
}
if(flag)
{
System.out.println("该英雄已经存在,无法进行插入");
}
else
{
//进行插入
heroNode.next=temp.next;
temp.next=heroNode;
}
}
//修改英雄的信息,不能改no,因为no是英雄的唯一标志,修改了相当于新添加了一个
public void update(HeroNode newHeroNode)
{
if(head.next==null)
{
System.out.println("链表为空");
return;
}
HeroNode temp=head.next;
//标志当前链表中有没有该英雄
boolean flag=false;
while(true)
{
if(temp==null)
{
//说明已经到了链表末尾
break;
}
if(temp.no==newHeroNode.no)
{
//表示已经找到该英雄
flag=true;
break;
}
temp=temp.next;
}
if(flag)
{
//更改英雄的内容
temp.name=newHeroNode.name;
temp.nikename=newHeroNode.nikename;
}
else
{
//说明该链表中没有该英雄
System.out.println("链表中没有该英雄");
}
}
//删除英雄的结点
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.println("要删除的结点不存在");
}
}
//遍历链表
public void show()
{
//判断链表是否为空
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;
}
}
}
5.测试结果
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=3216:D:\IntelliJ IDEA\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\1\IdeaProjects\algorithm\out\production\algorithm" cn.zzw.algorithm.LinkedList.SingleLinkedListDemo
更改英雄之前的链表
HeroNode{no=1, name='宋江', nikename='及时雨'}
HeroNode{no=2, name='卢俊义', nikename='玉麒麟'}
HeroNode{no=3, name='吴用', nikename='智多星'}
HeroNode{no=4, name='林冲', nikename='豹子头'}
更改英雄之后的链表
HeroNode{no=1, name='宋江', nikename='及时雨'}
HeroNode{no=2, name='卢俊义', nikename='玉麒麟'}
HeroNode{no=3, name='有用', nikename='小智'}
HeroNode{no=4, name='林冲', nikename='豹子头'}
删除英雄之前的链表
HeroNode{no=1, name='宋江', nikename='及时雨'}
HeroNode{no=2, name='卢俊义', nikename='玉麒麟'}
HeroNode{no=3, name='有用', nikename='小智'}
HeroNode{no=4, name='林冲', nikename='豹子头'}
删除英雄之后的链表
HeroNode{no=2, name='卢俊义', nikename='玉麒麟'}
HeroNode{no=3, name='有用', nikename='小智'}
HeroNode{no=4, name='林冲', nikename='豹子头'}
Process finished with exit code 0