1、链表介绍:
- 链表是以节点的方式来存储,是链式存储的
- 每个节点包含data域、next域(指向下一个节点)
- 每个节点不一定是链式存储的
- 链表分带头结点和不带头节点
- 链表不是连续存储的
内存中:
逻辑上:
2、代码展示:
package LinkedList;
public class singleLinkedList {
public static void main(String[] args) {
//进行测试
//先创建节点
Hero hero1 =new Hero(1,"宋江","及时雨");
Hero hero2 =new Hero(2,"卢俊义","玉麒麟");
Hero hero3 =new Hero(3,"吴用","智多星");
Hero hero4 =new Hero(4,"林冲","豹子头");
//创建链表
SingleLinked singleLinked = new SingleLinked();
//加入
singleLinked.add(hero1);
singleLinked.add(hero2);
singleLinked.add(hero3);
singleLinked.add(hero4);
//加入按照编号格式
singleLinked.addByOrder(hero1);
singleLinked.addByOrder(hero4);
singleLinked.addByOrder(hero3);
singleLinked.addByOrder(hero2);
//测试修改的代码
Hero newHeroNode = new Hero(2,"123","456");
singleLinked.update(newHeroNode);
//删除一个节点
singleLinked.del(4);
//显示一下
singleLinked.list();
}
}
//定义SingleLinkedList 管理我们的英雄
class SingleLinked{
//先初始化一个头结点,头结点不能动,不存放具体的数据
private Hero head = new Hero(0,"","");
//添加节点到单向链表
//思路,当不考虑编号顺序时
//1、找到当前链表的最后节点
//2、将最后这个节点的next指向新的节点
public void add(Hero Hero) {
//因为头节点不能动,因此我们需要一个辅助变量
Hero temp = head;
System.out.println("temp----------"+temp);
//遍历链表,找到最后
while(true) {
//找到链表最后
System.out.println("temp.next-----------"+temp.next);
if(temp.next==null) {
break;
}
//如果没有找到最后,就将temp后移
temp=temp.next;
}
//当退出while循环时,temp就指向了链表的最后
//将最后这个节点的next指向新的节点
temp.next=Hero;
}
//第二种方法在添加英雄时,根据排名将英雄插入到指定位置
//如果有这个排名,则添加失败,
public void addByOrder(Hero Hero) {
// //因为头节点不能动,因此我们仍然通过一个辅助指针(变量)来帮助找到添加地位置
// //因为单链表,所以我们找的temp是位于添加位置的前一个节点,否则插入不了
Hero temp = head;
boolean flag = false;//flag标志添加位置的前一个节点,否则插入不了
while(true) {
if(temp.next==null) {//说明temp已经在链表最后
break;
}if(temp.next.no>Hero.no) {//位置找到 就在temp后面插入
break;
}else if(temp.next.no==Hero.no) {//希望添加的Hero的标号已经添加
flag=true;
break;
}
temp=temp.next;//后移 遍历当前的链表
}
//判断flag的值,
if(flag) {//不能添加说明编号存在
System.out.println("准备插入的英雄的编号%d已经存在"+Hero.no);
}else {
Hero.next=temp.next;
temp.next=Hero;
}
}
//修改节点的信息,根据编号来修改,编号不能改
//1、根据newHeroNode的no来修改即可
public void update(Hero newHeroNode) {
//判断是否为空
if(head.next==null) {
System.out.println("链表为空");
return;
}
//找到需要修改的节点,根据编号
//定义一个辅助变量
Hero temp = head.next;
boolean flag = false;//表示是否找到该节点
while(true) {
if(temp==null) {
break;//到链表的最后
}
if(temp.no==newHeroNode.no) {
flag=true;
break;
}
temp=temp.next;
}
//根据flag判断是否找到修改的节点
if(flag) {
temp.name=newHeroNode.name;
temp.nextName=newHeroNode.nextName;
}else {//没有找到
System.out.println("没有找到编号为"+newHeroNode.no+"的节点");
}
}
//
//删除节点
//思路
//1、head节点不能动,因此我们需要一个temp辅助节点找到待删除节点的前一个节点
//2、我们在比较时,是temp.next.no和需要删除的节点的no比较
public void del(int no) {
Hero 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) {
System.out.println("链表为空");
return;
}
//因为头节点不能动,因此我们需要一个辅助节点来遍历
Hero temp = head.next;
while(true) {
if(temp==null) {
break;
}
//输出节点的信息
System.out.println("-------------"+temp);
//将next后移
temp=temp.next;
}
}
}
//定义Hero,每个Hero对象就是一个节点
class Hero{
public int no;
public String name;
public String nextName;
public Hero next;//指向下一个节点的域
public Hero(int hNo,String Hname,String NextName) {
this.no=hNo;
this.name=Hname;
this.nextName=NextName;
}
//
@Override
public String toString() {
return "Hero [no=" + no + ", name=" + name + ", nextName=" + nextName + "]";
}
}