说在前面:过年这几天想学习却静不下心,一个单链表看了5天,,,咳咳,好了,现在来总结下但单链表的一些简单的东西
1.什么是链表
链表是有序的列表,但是他在内存中的存储和列表并不一样,如图
链表是以节点的方式来存储数据的,是链式存储,他的每个节点分为两部分,data域和next指针域,data域是用来保存该节点的数据,next域用来指向下一个节点,所以链表中的各个节点并不一定是连续存储的。
逻辑示意图如下
2.如何创建一个单链表
为了更形象的说明,我们来创建一个水浒英雄的单链表,并构造一个水浒英雄的单链表的构造器
package linkedlist;
public class nodehero {
public int no;
public String name;
public String nickname;
public nodehero next;
//构造器
public nodehero(int no,String name,String nickname) {
this.no=no;//英雄编号
this.name=name;//英雄名字
this.nickname=nickname;//英雄昵称
}
//为了显示方法,我们重写tostring方法
@Override
public String toString() {
return "nodehero [no=" + no + ", name=" + name + ", nickname=" + nickname +"]";
}
}
接下来我们开始构造单链表
package linkedlist;
public class singlelinkedlist {
//初始化头节点
private nodehero head=new nodehero(0,"","");
}
//显示链表
public void list() {
if(head.next==null) {
System.out.println("链表为空");
return;
}
nodehero temp=head.next;
while(true) {
if(temp==null) {
break;
}
System.out.println(temp);
temp=temp.next;
}
}
3.单链表的应用(增删改查)
3.1添加节点
现在的链表里我们只有一个head头节点,当我们要往里面添加节点实际上就是将链表的尾节点next域指向我们所要添加的节点,但是头节点我们显然不能动,所以我们需要一个辅助变量temp来帮我们完成
public void add(nodehero nodehero) {
//head节点不能动,所以我们需要一个辅助变量temp
nodehero temp=head;
//遍历链表
while(true) {
//找到链表的最后
if(temp.next==null) {
break;
}
temp=temp.next;
}
temp.next=nodehero;
}
此时问题来了,这样的添加方法并不是按顺序添加,或者说即使是要添加相同的英雄也是没问题的,但是这显然不符合实际,所以我们需要一个能按顺序插入链表并且查重的方法
public void addByorder(nodehero nodehero) {
nodehero temp=head;
boolean flag=false;//判断是否存在相同编号的标志
while(true) {
if(temp.next==null) {
break;
}else if(temp.no==nodehero.no) {//当添加的节点的英雄编号和链表里节点的英雄编号一致时
flag=true;
}else if(temp.next.no>nodehero.no) {//当你所插入的英雄编号大于当前遍历的节点并且小于下一个节点的英雄编号时
break;
}
temp=temp.next;
}
if(flag) {
System.out.println("编号已存在");
}else {
nodehero.next=temp.next;//插入
temp.next=nodehero;
}
}
测试代码
package linkedlist;
public class singlelinkedlistdemo {
public static void main(String[] args) {
singlelinkedlist s=new singlelinkedlist();
nodehero hero1=new nodehero(1,"宋江","及时雨");
nodehero hero2=new nodehero(2,"卢俊义","玉麒麟");
nodehero hero3=new nodehero(3,"吴用","智多星");
s.add(hero1);
s.add(hero2);
s.add(hero3);
s.list();
}
}
3.2修改节点
修改节点时我们的依据依旧是英雄编号,思路就是根据你要修改的英雄编号去链表里遍历,当找到一样的编号的时候就将修改的信息添加进去
public void change(nodehero nodehero) {
boolean flag=false;
nodehero temp=head;
while(true) {
if(temp.next==null) {
break;
}
if(temp.no==nodehero.no) {
flag=true;
break;
}
temp=temp.next;
}
if(flag) {
temp.no=nodehero.no;
temp.name=nodehero.name;
temp.nickname=nodehero.nickname;
}else {
System.out.println("没有此英雄");
}
}
测试代码
package linkedlist;
public class singlelinkedlistdemo {
public static void main(String[] args) {
singlelinkedlist s=new singlelinkedlist();
nodehero hero1=new nodehero(1,"宋江","及时雨");
nodehero hero2=new nodehero(2,"卢俊义","玉麒麟");
nodehero hero3=new nodehero(3,"吴用","智多星");
s.add(hero1);
s.add(hero2);
s.add(hero3);
s.list();
nodehero hero4=new nodehero(2,"卢卢","鸹貔");
s.change(hero4);
System.out.println("-----");
s.list();
}
}
3.3删除节点
删除节点的思路并不是直接把节点删掉,而是将要删的节点根据其英雄编号在链表中遍历,并且我们必须找到相同编号的前一个,也就是说temp.next是我们要删的节点,当找到之后我们只需将temp.next=temp.next.next即可
public void del(nodehero nodehero) {
nodehero temp=head;
boolean flag=false;
while(true) {
if(temp.next==null) {
break;
}
if(temp.next.no==nodehero.no) {
flag=true;
break;
}
temp=temp.next;
}
if(flag) {
temp.next=temp.next.next;
}else {
System.out.println("没有找到此节点,无法删除");
}
}
测试代码
package linkedlist;
public class singlelinkedlistdemo {
public static void main(String[] args) {
singlelinkedlist s=new singlelinkedlist();
nodehero hero1=new nodehero(1,"宋江","及时雨");
nodehero hero2=new nodehero(2,"卢俊义","玉麒麟");
nodehero hero3=new nodehero(3,"吴用","智多星");
s.add(hero1);
s.add(hero2);
s.add(hero3);
s.list();
nodehero hero4=new nodehero(2,"卢卢","鸹貔");
s.change(hero4);
System.out.println("-----");
s.list();
System.out.println("----");
s.del(hero4);
s.list();
}
}
3.4查询
查询思路其实很简单就是拿着编号去遍历,我就不多说了,直接上代码
public void query(int num) {
nodehero temp=head;
boolean flag=false;
while(true) {
if(temp.no==num) {
flag=true;
break;
}
if(temp.next==null) {
break;
}
temp=temp.next;
}
if(flag) {
System.out.println("你所查询的英雄编号是"+temp.no+",英雄名称是"+temp.name+",英雄昵称是"+temp.nickname);
}else {
System.out.println("没有此英雄");
}
}
测试代码
s.query(3);