链表反转思路(简述):
链表分为单链表和双链表,细分为单向循环链表和双向循环链表。本章节主要讲述单向链表的反转。在接触到这张文章之前相信大家已经对链表(链表的组成部分)有所了解,链表内部由节点构成,每个节点又包含数据域和指针域,数据域用来存储数据,指针域用来存储内存地址,用来指向下一个节点。
链表反转的时候,每个节点的指针都要指向前一个节点。
所谓链表的反转简单说就是将节点的指针进行逆向指向,比如现在有4个引用变量,next(指向下个节点的指针),pre(节点的前驱),newhead(当前节点),nexthead(后继),反转的时候我们需要将每个节点指向下个节点的指针进行临时存储,因为链表如果先反转,后面的节点就会和前面的节点断开,所以我们需要存储这段指针,以便最后指针的后移。接下来我们用代码来说明:
public class Linode<E> { //创建节点类
E data; //创建数据域
Linode<E> next; //指针域
public Linode(E data) { //数据域赋值
this.data = data;
}
public boolean add(E data){ //添加元素的方法
Linode<E> newnode = new Linode<>(data); //创建新的节点,传入数据
if(this.next == null){
this.next = newnode; //指向写下个节点的指针指向新节点
}else{
this.next.add(data); //指针向后移动并调用add方法添加该元素
}
return true;
}
public void print(){ //输出链表
System.out.println(this.data); //输出该指针域的数据
if(this.next != null){
System.out.println("-->");
this.next.print(); //递归调用本身
}
}
public Linode<E> reverlist(Linode<E> head){ //反转方法,传递一个头节点
Linode<E> pre = null; //链表前驱
Linode<E> newhead = head; //当前节点
Linode<E> next1 = null; //后继(存储指向下一个节点的地址)
while (newhead != null){ //当前节点不为空时
next1 = newhead.next; //存储指向下个节点的地址
newhead.next = pre; //当前节点的指针指向前驱
pre = newhead; //前驱指针向后移动
newhead = next1; //当前节点的指针向后移动
}
return pre; //返回前驱
}
public static void main(String[] args) {
Linode<Integer> lin = new Linode<>(1); //构造器初始化第一个节点
lin.add(2);
lin.add(3);
lin.add(4);
lin.add(5);
lin.add(6);
System.out.println("before:");
lin.print();
System.out.println("after:");
System.out.println(lin.reverlist(lin.next).data);
}
}
上述代码运行结果如下图所示:
最后返回出一个头节点,反转链表有其它方法如:出栈法,三指针法,递归法本章将不做介绍。