链表介绍
·链表是有序的列表
·链表是以节点的方式来储存
·每个节点包含data域,next域
·链表各节点不一定是连续存储
·链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定
链表在内存存储如下
注:链表可以理解为寻找宝藏,以头指针为第一幅藏宝图,data中是宝藏碎片,next是下一个宝藏碎片的藏地,每块藏地不一定在一起,可能相差十万八千里,但是每处藏地都会有一份宝藏碎片,和前往下一处藏地的地图,以第一处(头指针)开始跟着一步一步得到所有钥匙碎片,最后到NULL得到完整的宝藏(全部数据)。
链表构成
因为每个节点都包含数据内容和指向下一节点的索引,所以我们可以将其包装成一个类来处理
class Node{
public int no;
public String name;
public Node next;//指向下一个节点
}
添加链表
顺序添加链表(代码实现)
package datastructure;
public class linkedIist1 {
public static void main(String[] args) {
//进行测试
//创建节点
Node node1=new Node(1,"一号") ;
Node node2=new Node(2,"二号") ;
Node node3=new Node(3,"三号") ;
Node node4=new Node(4,"四号") ;
Node node5=new Node(5,"五号") ;
//创建链表
linked link=new linked();
link.addLinked(node1);
link.addLinked(node2);
link.addLinked(node3);
link.addLinked(node4);
link.addLinked(node5);
//显示列表
link.show();
}
}
class linked{
private Node head=new Node(0,"");
public void addLinked(Node node){
Node temp=head;//因为head节点不能动,所以另外定义一个变量,将head节点赋给它
//进行遍历找到链表的最后一个节点
while(true){
if(temp.next==null)
break;
temp=temp.next;
}
//将新节点接到原链表尾,新的节点代替了null
temp.next=node;
}
public void show(){
if(head.next==null){
System.out.println("链表为空");
return;
}
//head节点不能动
Node temp=head.next;
while (true){
if (temp==null){
break;
}
System.out.println(temp);
temp=temp.next;
}
}
}
class Node {
public int no;
public String name;
public Node next;//指向下一个节点
//构造器
public Node(int no, String name){
this.no=no;
this.name=name;
}
@Override
public String toString() {
return "Node{" +
"no=" + no +
", name='" + name + '\'' +
'}';//不加next域,否则会把后面的节点打出
}
}
数据按照序号添加链表
因为正常节点是按照尾接的方式连接的,为了按照序号重新插入拼接,这里我们需要一个辅助节点temp,辅助节点遍历整个链表的序号然后与添加节点做比较,来选择添加节点的插入位置,因为链表节点连接需要next即后连接,所以序号比较时,往往是remp.next的序号与添加节点序号对比,而不是temp的序号。
代码实现
package datastructure;
public class linkedIist2 {
public static void main(String[] args) {
//进行测试
//创建节点
Node2 node1=new Node2(1,"一号") ;
Node2 node2=new Node2(2,"二号") ;
Node2 node3=new Node2(3,"三号") ;
Node2 node4=new Node2(4,"四号") ;
Node2 node5=new Node2(5,"五号") ;
//创建链表
linked2 link=new linked2();
//所添加数据按照序号排列
link.addByNo(node1);
link.addByNo(node5);
link.addByNo(node2);
link.addByNo(node4);
link.addByNo(node3);
//显示列表
link.show();
}
}
class linked2 {
private Node2 head = new Node2(0, "");
public void addByNo(Node2 node) {
Node2 temp = head;//因为head节点不能动,所以另外定义一个变量,将head节点赋给它
//进行遍历找到链表的最后一个节点
boolean flag = false;//flag表示节点是否存在,默认为flase(加入节点是否与原有节点相同)
while (true) {
if (temp.next == null)
break;
if (temp.next.no > node.no)//因为链表只能后接所以与要添加变量比较序号的是temp.next而不是temp
break;
else if (temp.next.no == node.no) {
flag = true;//序号存在
break;
}
temp = temp.next;
}
if (flag) {//编号存在,不能添加
System.out.println("插入序号已存在");
} else {//编号不存在,可以添加
node.next = temp.next;//将原节点的next赋给插入节点
temp.next = node;//将插入节点赋给将原节点的next
}
}
public void show() {
if (head.next == null) {
System.out.println("链表为空");
return;
}
//head节点不能动
Node2 temp = head.next;
while (true) {
if (temp == null) {
break;
}
System.out.println(temp);
temp = temp.next;
}
}
}
class Node2 {
public int no;
public String name;
public Node2 next;//指向下一个节点
//构造器
public Node2(int no, String name){
this.no=no;
this.name=name;
}
@Override
public String toString() {
return "Node2{" +
"no=" + no +
", name='" + name + '\'' +
'}';//不加next域,否则会把后面的节点打出
}
}
修改链表
思路分析
通过对序号遍历索引,然后在对data域进行修改
更新或修改数据(代码实现)(方法段)
public void update(Node2 newNode){
Node2 temp=head.next;
if (temp==null){
System.out.println("链表为空");
}
//更新(修改)链表节点前先找到该节点
boolean flag=false;//定义一个变量表示是否更新节点是否在链表内
while (true){
if (temp==null)
break;
if (temp.no==newNode.no){
flag=true;
break;
}
temp=temp.next;
}
if (flag){
temp.name=newNode.name;
}else{//没有找到节点
System.out.println("未找到该节点,无法修改");
}
}
(测试段)
Node2 node1=new Node2(1,"一号") ;
Node2 node2=new Node2(2,"二号") ;
Node2 node3=new Node2(3,"三号") ;
Node2 node4=new Node2(4,"四号") ;
Node2 node5=new Node2(5,"五号") ;
//创建链表
linked2 link=new linked2();
//所添加数据按照序号排列
link.addByNo(node1);
link.addByNo(node5);
link.addByNo(node2);
link.addByNo(node4);
link.addByNo(node3);
//测试修改节点
Node2 Tnode=new Node2(2,"贰号") ;
link.update(Tnode);
//显示列表
link.show();
删除链表
思路分析
·我们需要先找到删除节点的前一个节点(原因同上)
·引入辅助变量temp,temp.next=temp.next.next
·被删除的节点,将不会有其他引用指向,会被垃圾回收机制回收
删除链表(代码实现)(方法段)
public void delete(int no){
Node2 temp=head.next;
boolean isFind=false;
if(temp==null){
System.out.println("链表为空,无法删除");
}
while (true){
if(temp.next==null){
break;
}
if (temp.next.no==no){
isFind=true;
break;
}
temp=temp.next;
}
if(isFind){
temp.next=temp.next.next;
}else{
System.out.println("未找到序号所对应的节点,删除失败");
}
}
ps:删除与前两个主要思路一致,代码不再做详解