链表介绍
- 链表是以结点的方式来存储,是链式存储
- 每个结点包含data域,next域;指向下一个结点
- 链表的每一个结点不一定是连续存储的
- 链表分带头结点的和没有头结点的链表
代码实现
先定义一个几点reverseHead=newHeroNode
从头遍历原本的链表,每遍历一个结点,取出一个结点放在新的链表(reverseHead)的最前面
原本的链表head.next=reverseHead.next
原本的链表:
期望的链表:
过程:
PS:
1. head节点不存放具体的数据,用于表示单链表的头
2. reverseHead节点和head节点相同
实现反转的方法:
public void reversetList(HeroNode head){
// 如果当前链表为空,或者只有一个结点,无需反转,直接返回
if(head.next==null || head.next.next==null){
return;
}
// 定义一个辅助变量,遍历原本的链表
HeroNode cur=head.next;
HeroNode next=null; // 指向当前结点的下一个结点
HeroNode reverseHead=new HeroNode(0,"","");
// 遍历原来的链表,遍历一个结点,取出后放在新的链表中
while (cur!=null){
next=cur.next;// 暂时保存当前结点的下一个结点
cur.next=reverseHead.next;
reverseHead.next=cur; // 将cur链接到新的链表
cur=next;
}
// 实现单链表的反转
head.next=reverseHead.next;
}
实现结果:
附加代码:
public static void main(String[] args) {
HeroNode heroNode1 = new HeroNode(1, "张新某某", "霸气");
HeroNode heroNode2 = new HeroNode(2, "苑仁某某", "不服输");
HeroNode heroNode3 = new HeroNode(3, "张慧某某", "美丽");
// 创建链表
SingleLinkedList singleLinkedList=new SingleLinkedList();
// 加入
singleLinkedList.addByOrder(heroNode1);
singleLinkedList.addByOrder(heroNode3);
singleLinkedList.addByOrder(heroNode2);
// 显示
System.out.println("显示原本的单链表~");
singleLinkedList.list();
System.out.println("==================");
// 单链表的反转
System.out.println("反转后的单链表");
singleLinkedList.reversetList(singleLinkedList.getHead());
singleLinkedList.list();
}
节点HeroNode:
public 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 "HerodNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\''+
'}';
}
}
针对节点HeroNode的操作:
public class SingleLinkedList {
// 初始化一个头结点
private HeroNode head=new HeroNode(0,"","");
public HeroNode getHead() {
return head;
}
// 添加节点到单向链表
public void add(HeroNode heroNode){
// 因为head节点不能动,因此我们需要一个辅助遍历temp
HeroNode temp=head;
// 遍历链表,找到最后
while (true){
if (temp.next==null){
break;
}
// 如果没有找到,将temp后移
temp=temp.next;
}
temp.next=heroNode;
}
// 添加的第二种方式(按照编号的顺序)
public void addByOrder(HeroNode heroNode){
System.out.println("输入的数据:"+heroNode);
HeroNode temp=head;
boolean flag=false;// flag 标志添加的编号是否存在
while (true){
if (temp.next==null){
break;
}
if (temp.next.no>heroNode.no){
break;
}else if (temp.next.no==heroNode.no){
flag=true;
break;
}
temp = temp.next;
}
if (flag){
System.out.println("将要插入的编号已经存在,不能插入");
}else {
System.out.println("heroNode.next=temp.next:"+heroNode.next+"="+temp.next);
heroNode.next=temp.next;
temp.next=heroNode;
}
}
// 修改链表
public void update(HeroNode heroNode){
// 判断是否为空
if(head.next==null){
System.out.println("链表为空~");
return;
}
HeroNode temp=head.next;
boolean flag=false;// 表示是否找到该节点
while (!flag){
if (temp==null){
break;// 已经遍历完链表
}
if (temp.no==heroNode.no){
flag=true;
break;
}
temp=temp.next;
}
if (flag){
temp.name=heroNode.name;
temp.nickname=heroNode.nickname;
}else {
System.out.println("没有找到对应的编号");
}
}
// 显示链表
public void list(){
// 判断链表是否为空
if(head.next==null){
System.out.println("链表为空");
return;
}
// 因为头节点,不能动,因此我们需要一个辅助变量来遍历
HeroNode temp=head.next;
while (true){
if (temp==null){
break;
}
// 输出节点信息
System.out.println(temp);
// 将temp后移
temp=temp.next;
}
}
// 删除结点
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;
}
if(flag){
temp.next=temp.next.next;
}else {
System.out.println("要删除的结点不存在");
}
}
/**
* 返回有效节点的个数
* @param head 链表的头结点
*/
public int getLength(HeroNode head){
// 判断链表不为空
if (head.next==null){
return 0;
}
int length=0;// 统计链表的节点个数
HeroNode cur=head.next;
System.out.println("alal :"+head.next);
while (cur!=null){
length++;
System.out.println("cur :"+cur);
cur=cur.next;
}
return length;
}
}