【简介】
链表是有序的列表,它在内存中是存储如下:
- 链表是以节点的方式来存储,是链式存储
- 每个节点包含 data 域, next 域:指向下一个节点.
- 如图:链表的各个节点不一定是连续存储.
- 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定
【单项链表】
单链表(带头结点) 逻辑结构示意图如下
【实例演示】
使用带head头的单向链表实现 –水浒英雄排行榜管理
1)完成对英雄人物的增删改查操作
2)第一种方法在添加英雄时,直接添加到链表的尾部
3)第二种方式在添加英雄时,根据排名将英雄插入到指定位置(如果有这个排名,则添加失败,并给出提示)
【实例分析一】
第一种方式(按照顺序添加,从尾部插入,不考虑排名)
【代码实现】——单向链表的创建
public class Demo1 {
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 singleLinkedList = new SingleLinkedList();
singleLinkedList.add(hero1);
singleLinkedList.add(hero4);
singleLinkedList.add(hero3);
singleLinkedList.add(hero2);
//显示链表
singleLinkedList.list();
}
}
//定义链表
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;
heroNode.next=null;
}
//显示遍历
public void list() {
//判断链表是否为空
if(head.next==null) {
System.out.println("链表为空");
return;
}
//因为头结点不能动,所以需要一个新的变量
HeroNode temp = head.next;
while (temp!=null) {
System.out.println(temp);
temp=temp.next;
}
}
}
//定义一个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;
}
//重写tostring方法
@Override
public String toString() {
return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
}
}
【结果展示】
可以看到,如果我们改变插入的顺序,所得到的链表也是不一样的。
【实例分析二】
第二种方式(需要考虑排名,进行插入)
【代码实现】——单向链表的顺序插入
public class Demo2 {
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, "林冲","豹子头");
HeroNode hero5 = new HeroNode(4, "测试","测试项");
//创建链表
SingleLinkedList2 singleLinkedList2 = new SingleLinkedList2();
singleLinkedList2.add(hero4);
singleLinkedList2.add(hero1);
singleLinkedList2.add(hero3);
singleLinkedList2.add(hero2);
singleLinkedList2.add(hero5);
//显示链表
singleLinkedList2.list();
}
}
//定义链表
class SingleLinkedList2{
//初始化一个头结点
private HeroNode head = new HeroNode(0,"" , "");
//添加结点
public void add(HeroNode heroNode) {
HeroNode temp=head;
while (temp.next!=null) {
//将节点插入到合适的位置
if (temp.next.no>heroNode.no) {
heroNode.next=temp.next;
temp.next=heroNode;
return;
}else if (temp.next.no==heroNode.no) {
System.out.printf("准备插入的英雄编号%d已存在,不能加入!\n",heroNode.no);
return;
}
temp=temp.next;
}
temp.next=heroNode;
heroNode.next=null;
}
//显示遍历
public void list() {
//判断链表是否为空
if(head.next==null) {
System.out.println("链表为空");
return;
}
//因为头结点不能动,所以需要一个新的变量
HeroNode temp = head.next;
while (temp!=null) {
System.out.println(temp);
temp=temp.next;
}
}
}
//定义一个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;
}
//重写tostring方法
@Override
public String toString() {
return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
}
}
【效果展示】
可以看到,无论我们插入的顺序是怎样的,所有的节点都按照我们规定的方式,从小到大进行了排列。