链表
实际内存中的布局图
单链表
应用实例
第一种添加:
按顺序添加:
删除:
修改思路:
1.先找到该节点,通过辅助变量
2.修改
package lianbiao;
/**
* @author : sky
* @version : 1.0
*/
public class SingleLinkedListDemo{
public static void main(String[] args) {
//先创建节点
HeroNode node1=new HeroNode(1,"宋江","及时雨");
HeroNode node2=new HeroNode(2,"卢俊义","玉麒麟");
HeroNode node3=new HeroNode(3,"吴用","智多星");
HeroNode node4=new HeroNode(4,"林冲","豹子头");
//再创建链表
SingleLinkedList sll=new SingleLinkedList();
//加入
/*sll.add1(node1);
sll.add1(node2);
sll.add1(node3);
sll.add1(node4);*/
sll.addByOrder(node1);
sll.addByOrder(node4);
sll.addByOrder(node2);
sll.addByOrder(node3);
//显示
System.out.println("原来链表:");
sll.list();
System.out.println("--------------------------------------------");
System.out.println("反转链表:");
SingleLinkedList.reverseList(sll.getHead());
sll.list();
System.out.println("--------------------------------------------");
System.out.println("逆序打印单链表~");
SingleLinkedList.reversePrint(sll.getHead());
System.out.println("--------------------------------------------");
//修改节点
HeroNode newNode=new HeroNode(2,"小卢","玉麒麟~~");
sll.update(newNode);
sll.delete(4);
System.out.println(SingleLinkedList.getLength(sll.getHead()));
sll.list();
System.out.println("--------------------------------------------");
HeroNode res=SingleLinkedList.findLastIndexNode(sll.getHead(),3);
System.out.println(res);
}
}
//定义管理英雄
class SingleLinkedList {
//先初始化一个头节点,头节点不要动,不存放具体数据
private HeroNode head=new HeroNode(0,"","");
public HeroNode getHead() {
return head;
}
//添加节点到单向链表,直接添加到链表的最后
//思路:当不考虑编号顺序时;1.找到当前链表的最后节点;2.将最后这个next指向新的节点
public void add(HeroNode heroNode){
//因为head节点不能动,所以需要一个辅助变量
HeroNode temp=head;
//遍历链表,找到最后
while(true){
if(temp.next==null){
//找到了链表的最后
break;
}
temp=temp.next;//如果没有找到链表的最后,将temp后移
}
//当退出while循环时,temp就指向了链表的最后
//将最后这个节点next指向新的节点
temp.next=heroNode;
heroNode.next=null;
}
//第二种方式添加英雄,根据排名将英雄插入到指定位置
//如果有这个排名则给出提示添加失败
public void addByOrder(HeroNode heroNode){
//一个辅助变量
//因为时单链表,我们找的temp是要位于添加位置的前一个,否则插入不了
HeroNode temp=head;
//标志添加的编号是否存在,默认为false
boolean flag=false;
while(true){
if(temp.next==null){
break;
}
if(temp.next.no>heroNode.no){
//位置找到了,在temp后加入
break;
}else if(temp.next.no==heroNode.no){
//说明希望添加的节点已存在
flag=true;//说明编号存在
break;
}
temp=temp.next;//后移,遍历当前链表
}
//判断fla的值
if(flag){
System.out.printf("英雄编号 %d 已存在,不能再次加入\n",heroNode.no);
}else{
//插入到链表中,temp的后面
heroNode.next=temp.next;
temp.next=heroNode;
}
}
//修改节点的信息,根据no来修改,即no不能改
//1.根据heronode的no来修改即可
public void update(HeroNode heroNode){
//判断是否为空
if(head.next==null){
System.out.println("链表为空~");
return;
}
//定义辅助变量
HeroNode temp=head.next;
boolean flag=false;//表示是否找到该节点
//找到需要修改的节点
while(true){
if(temp==null){
break;//已经遍历完链表
}
if(temp.no==heroNode.no){
flag=true;//找到了
break;
}
temp=temp.next;
}
//根据flag判断是否找到要修改的节点
if(flag){
temp.name=heroNode.name;
temp.nickname=heroNode.nickname;
}else{
System.out.printf("没有找到编号为%d的节点,不能修改\n",heroNode.no);
}
}
//删除节点
//思路:1.head不能动,通过辅助节点temp找到删除节点的前一个节点
//2.说明我们在比较时,是temp next no与需要删除节点no比较
public void delete(int no){
//首先判断链表是否为空
if(head.next==null){
System.out.println("链表为空,不能删除节点~");
return;
}
HeroNode temp=head;//因为要指向删除节点的前一个,所以直接指向head
boolean flag=false;//标志是否找到待删除节点
while(true){
if(temp.next==null){
//已经到了链表的最后
break;
}
if(temp.next.no==no){
//找到的待删除节点的前一个节点temp
flag=true;
break;
}
temp=temp.next;
}
if(flag){
//找到了,可以删除
temp.next=temp.next.next;
}else{
System.out.printf("编号为%d的节点没有找到,不能删除\n",no);
}
}
//显示链表,也就是遍历
public void list(){
//先判断链表是否为空
if(head.next==null){
System.out.println("链表为空");
return;
}
//因为head节点不能动,所以需要一个辅助变量遍历
HeroNode temp=head.next;
while(true){
if(temp==null){
//找到了链表的最后
break;
}