本文已参与「新人创作礼」活动,一起开启掘金创作之路
1.链表是以节点的方式来存储,是链式存储 , 每个节点包含 data 域, next 域:指向下一个节点.
单链表的应用举例:
(1)先构造一个单链表对象
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;
}
}
2.添加数据进单链表
首先初始化一个头结点,因为头结点不能动,然后通过一个辅助变量temp来进行遍历链表,找到链表的最后节点,然后把最后节点的下一个节点(就是null)改为指向新加的节点
//先初始化一个头节点, 头节点不要动, 不存放具体的数据
private HeroNode head = new HeroNode(0, "", "");
//添加节点到单向链表
//思路,当不考虑编号顺序时
//1. 找到当前链表的最后节点
//2. 将最后这个节点的next 指向 新的节点
public void add(HeroNode heroNode) {
//因为head节点不能动,因此我们需要一个辅助遍历 temp
HeroNode temp = head;
//遍历链表,找到最后
while(true) {
//找到链表的最后
if(temp.next == null) {//
break;
}
//如果没有找到最后, 将将temp后移
temp = temp.next;
}
//当退出while循环时,temp就指向了链表的最后
//将最后这个节点的next 指向 新的节点
temp.next = heroNode;
}
3.按顺序添加数据进单链表
首先也是初始化一个头结点来进行辅助遍历,和设置一个boolean值来查看添加的编号是否已存在,设置好之后,先通过temp遍历发现三种情况,第一种:如果temp的下一个节点为空,则temp在链表的最后,直接添加进temp的下一个节点即可;第二种:如果temp的下一个节点的编号大于所要添加的数据节点,则把temp的下一个节点修改为新加的数据节点,而新的数据节点的下一个节点则修改为原先的temp的下一个节点(heroNode.next = temp.next; temp.next = heroNode;);第三种:如果所添加进去节点的编号已经存在,则boolean为true,说明编号存在,不能进行添加.
//第二种方式在添加英雄时,根据排名将英雄插入到指定位置
//(如果有这个排名,则添加失败,并给出提示)
public void addByOrder(HeroNode heroNode) {
//因为头节点不能动,因此我们仍然通过一个辅助指针(变量)来帮助找到添加的位置
//因为单链表,因为我们找的temp 是位于 添加位置的前一个节点,否则插入不了
HeroNode temp = head;
boolean flag = false; // 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) {//说明希望添加的heroNode的编号已然存在
flag = true; //说明编号存在
break;
}
temp = temp.next; //后移,遍历当前链表
}
//判断flag 的值
if(flag) { //不能添加,说明编号存在
System.out.printf("准备插入的英雄的编号 %d 已经存在了, 不能加入\n", heroNode.no);
} else {
//插入到链表中, temp的后面
heroNode.next = temp.next;
temp.next = heroNode;
}
}
4.删除单链表的数据
根据删除数据的编号来查找这条数据,最主要的一句是temp.next =temp.next.next;把temp的下一个节点数据(也就是要被删除数据的编号)指向为被删除数据的编号,而这样可以使得java的垃圾回收机制去回收没有被引用的数据(要被删除的数据)来进行一个删除
public void delete(HeroNode delheroNode) {
//因为头节点不能动,因此我们仍然通过一个辅助指针(变量)来帮助找到添加的位置
//因为单链表,因为我们找的temp 是位于 添加位置的前一个节点,否则插入不了
HeroNode temp = head;
boolean flag = false; // flag标志添加的编号是否存在,默认为false
while(true) {
if(temp.next == null) {//说明temp已经在链表的最后
System.out.println("链表无这东西");
break; //
}
if (temp.next.no == delheroNode.no) {//说明希望添加的heroNode的编号已然存在
flag = true; //说明编号存在
break;
}
temp = temp.next; //后移,遍历当前链表
}
//判断flag 的值
if(flag) { //不能添加,说明编号存在
temp.next =temp.next.next;
} else {
System.out.println("无这个英雄不能修改"+delheroNode.toString());
}
}
5.修改单链表的数据
具体和上面两个差不多
public void update(HeroNode heroNode) {
//因为头节点不能动,因此我们仍然通过一个辅助指针(变量)来帮助找到添加的位置
//因为单链表,因为我们找的temp 是位于 添加位置的前一个节点,否则插入不了
HeroNode temp = head;
boolean flag = false; // flag标志添加的编号是否存在,默认为false
while(true) {
if(temp.next == null) {//说明temp已经在链表的最后
break; //
}
if (temp.next.no == heroNode.no) {//说明希望添加的heroNode的编号已然存在
flag = true; //说明编号存在
break;
}
temp = temp.next; //后移,遍历当前链表
}
//判断flag 的值
if(flag) { //不能添加,说明编号存在
temp.next.no = heroNode.no;
temp.next.name=heroNode.name;
temp.next.nickName=heroNode.nickName;
} else {
System.out.println("无这个英雄不能修改"+heroNode.toString());
}
}
6.输出单链表
通过while循环做一个遍历
//显示链表[遍历]
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 = temp.next;
}
}