链表(Linked List)介绍
链表是有序的列表,但是它在内存中是存储如下
由上图可知
- 1 ) 链表是以节点的方式来存储,是链式存储
- 2)每个节点包含 data 域, next 域:指向下一个节点.
- 3)如图:发现链表的各个节点不一定是连续存储.
- 4)链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定
单链表(带头结点) 逻辑结构示意图如下
代码实现思路分析
- 1 创建一个节点类 HeroNode 【编号,姓名,昵称,下一个节点,构造器,toString方法】
- 2 创建管理英雄的类【初始化头节点,添加节点到链表的方法,,遍历链表】
- 1.初始化头节点
private HeroNode head = new HeroNode(0,"","");
1.2 .添加节点到链表
1.节点类
//1.先定义一个节点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 + '\'' +
'}';
}
}
1. 按照插入顺序
先初始化头节点,不动。然后添加方法
1.找到当前链表的最后一个节点,
2.将最后节点的next指向新的节点
//定义管理英雄的方法
class HeroList{
//1.初始化头节点,不要动,不妨数据
private HeroNode head = new HeroNode(0,"","");
//添加节点到单链表:(不考虑编号顺序)1.找到当前链表的最后一个节点,2.将最后节点的next指向新的节点
public void add(HeroNode heroNode) {
//因为头节点不能动,所以要借助一个临时变量
HeroNode temp = head;
//遍历链表,找到最后节点
while (true) {
//找到链表的最后
if (temp.next == null) {
break;
}
//如果没找到最后,将temp后移
temp = temp.next;
}
//当退出while循环时,temp就指向姐弟啊你的最后,将最后这个节点的next指向新的节点
temp.next = heroNode;
}
1. 按照编号顺序插入
1.找到新添加的节点位置:辅助变量遍历
* 2.新的节点.next = temp.next
* 3.将temp.next =新的节点
public void add2(HeroNode heroNode) {
//1.头节点不动,需要临时变量temp,我们要找的temp位于添加位置的前一个节点
HeroNode temp = head;
//2.flag标志添加的编号是否存在,默认为false
boolean flag = false;
while (true) {
if (temp.next == null){
break; //temp已经在链表最后了
}
if (temp.next.no > heroNode.no){
break; //位置找到了,就在temp后面插入
}else if (temp.next.no == heroNode.no){
flag = true;
break; //说明编号存在
}
temp = temp.next; //将temp后移,遍历当前链表
}
//判断flag的值
if (flag) {
System.out.printf("准备插入的编号%d已经存在,不能加入\n",heroNode.no);
}else {
//插入链表中,temp的后面
heroNode.next = temp.next;
temp.next = heroNode;
}
}
显示遍历链表
/**
* 显示链表【遍历】
*/
public void list(){
//1.先判断是否为空
if (head.next == null) {
System.out.println("链表为空");
return;
}
//2.头节点不动 新节点遍历
HeroNode temp = head.next;
while (true) {
//判断链表是否到了最后
if (temp==null){
break;
}
//输出节点信息,并且将temp后移
System.out.println(temp);
temp = temp.next;
}
}
修改链表
/**
* 修改链表 --- 根据no编号修改,no不变
* @param newHeroNode
*/
public void update(HeroNode newHeroNode){
//1.判空
if (head.next == null){
System.out.println("链表为空");
return;
}
//2.定义临时temp 找到需要修改的节点
HeroNode temp = head.next;
boolean flag = false;
while (true){
if (temp == null) {
break; //链表到头 遍历结束
}
if (temp.no == newHeroNode.no){
flag = true;
break; //找到了
}
temp = temp.next;
}
//退出循环有两种可能,1没找到,2找到了
if (flag){
temp.name=newHeroNode.name;
temp.nickName = newHeroNode.nickName;
}else{
System.out.println("该节点不存在,请重试!");
}
}
删除链表
/**
* 删除节点
* @param no
*/
public void del(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; //temp后移
}
if (flag) {
temp.next = temp.next.next;
}else {
System.out.println("要删除的节点不存在");
}
}
总体代码
package com.wei.linkedlist;
/**
* 单链表的实现 --- 按照添加的顺序来实现
* 1.创建一个节点类 HeroNode 【编号,姓名,昵称,下一个节点,构造器,toString方法】
* 2.创建管理英雄的方法 【初始化头节点,添加节点到链表的方法,,遍历链表】
* 1.初始化头节点
* private HeroNode head = new HeroNode(0,"","");
* 1.添加节点到链表
* 1.因为头节点不能动,所以要借助一个临时变量
* HeroNode temp = head;
* 2. 遍历链表,找到最后节点
* 1.找到链表的最后 ,如果没找到最后,将temp后移
* 2.当退出while循环时,temp就指链表的最后,将最后这个节点的next指向新的节点
* 2. 遍历显示边表
* 1./1.先判断是否为空
* 2.头节点不动 新节点遍历
* 3.输出节点信息,并且将temp后移
*
*
*/
public class SingleLinked {
public static void main(String[] args) {
//1.创建一个节点
HeroNode heroOne = new HeroNode(1, "宋江", "及时雨");
HeroNode heroTwo = new HeroNode(2, "小航", "智多星");
HeroNode heroThree = new HeroNode(3, "南笙", "林楠笙");
HeroNode heroFour= new HeroNode(4, "林冲", "豹子头");
//2.将节点添加到链表中
HeroList list = new HeroList();
// list.add(heroOne);
// list.add(heroThree);
// list.add(heroFour);
// list.add(heroTwo);
// 测试顺序插入
list.add2(heroThree);
list.add2(heroFour);
list.add2(heroOne);
list.add2(heroTwo);
System.out.println("---修改之前--------");
list.list();
//测试修改代码
HeroNode newHero = new HeroNode(2, "小sddsd航", "智多发DVD发v星");
System.out.println("---修改之后--------");
list.update(newHero);
//删除一个节点
list.del(4);
list.del(1);
list.del(2);
list.del(3);
//3.遍历链表
list.list();
}
}
//定义管理英雄的方法
class HeroList{
//1.初始化头节点,不要动,不妨数据
private HeroNode head = new HeroNode(0,"","");
//添加节点到单链表:(不考虑编号顺序)1.找到当前链表的最后一个节点,2.将最后节点的next指向新的节点
public void add(HeroNode heroNode) {
//因为头节点不能动,所以要借助一个临时变量
HeroNode temp = head;
//遍历链表,找到最后节点
while (true) {
//找到链表的最后
if (temp.next == null) {
break;
}
//如果没找到最后,将temp后移
temp = temp.next;
}
//当退出while循环时,temp就指向姐弟啊你的最后,将最后这个节点的next指向新的节点
temp.next = heroNode;
}
/**
*添加方式二:通过编号添加
* 1.找到新添加的节点位置:辅助变量遍历
* 2.新的节点.next = temp.next
* 3.将temp.next =新的节点
*/
public void add2(HeroNode heroNode) {
//1.头节点不动,需要临时变量temp,我们要找的temp位于添加位置的前一个节点
HeroNode temp = head;
//2.flag标志添加的编号是否存在,默认为false
boolean flag = false;
while (true) {
if (temp.next == null){
break; //temp已经在链表最后了
}
if (temp.next.no > heroNode.no){
break; //位置找到了,就在temp后面插入
}else if (temp.next.no == heroNode.no){
flag = true;
break; //说明编号存在
}
temp = temp.next; //将temp后移,遍历当前链表
}
//判断flag的值
if (flag) {
System.out.printf("准备插入的编号%d已经存在,不能加入\n",heroNode.no);
}else {
//插入链表中,temp的后面
heroNode.next = temp.next;
temp.next = heroNode;
}
}
/**
* 显示链表【遍历】
*/
public void list(){
//1.先判断是否为空
if (head.next == null) {
System.out.println("链表为空");
return;
}
//2.头节点不动 新节点遍历
HeroNode temp = head.next;
while (true) {
//判断链表是否到了最后
if (temp==null){
break;
}
//输出节点信息,并且将temp后移
System.out.println(temp);
temp = temp.next;
}
}
/**
* 修改链表 --- 根据no编号修改,no不变
* @param newHeroNode
*/
public void update(HeroNode newHeroNode){
//1.判空
if (head.next == null){
System.out.println("链表为空");
return;
}
//2.定义临时temp 找到需要修改的节点
HeroNode temp = head.next;
boolean flag = false;
while (true){
if (temp == null) {
break; //链表到头 遍历结束
}
if (temp.no == newHeroNode.no){
flag = true;
break; //找到了
}
temp = temp.next;
}
//退出循环有两种可能,1没找到,2找到了
if (flag){
temp.name=newHeroNode.name;
temp.nickName = newHeroNode.nickName;
}else{
System.out.println("该节点不存在,请重试!");
}
}
/**
* 删除节点
* @param no
*/
public void del(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; //temp后移
}
if (flag) {
temp.next = temp.next.next;
}else {
System.out.println("要删除的节点不存在");
}
}
}
//1.先定义一个节点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 + '\'' +
'}';
}
}