单链表反转是面试时经常会遇到的问题,之前只是在数据结构里用伪代码实现过单链表反转。为落实亲手编写每一个程序的目标,在这里用java实现反转。方法有很多,这里只写最优的。时间复杂度O(n),空间复杂度O(1)。也就是说不新开辟空间,原地反转。
这篇博客主要讲述如何采用头插和尾插两种方法建立单链表。反转链表见下一篇博客。
不管采用哪种方法,首先应创建表头,目的是使第一个实际节点和后面的节点是等同的,不会因为删除、插入等操作区分开考虑。
头插法:不断的将新节点插入到表头后面。
package singleLinklistReverse;
public class Creat {
//定义节点类
public class Lnode{
int data;
Lnode next;
}
public void creatLinklist(String s){
Lnode first=new Lnode();
first.next=null;
for(int i=0;i<s.length();i++){
Lnode lnode=new Lnode();
lnode.data=s.charAt(i)-'0';
lnode.next=first.next;
first.next=lnode;
}
Lnode p=first.next;
while(p!=null){
System.out.println(p.data);
p=p.next;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner=new Scanner(System.in);
String s=scanner.nextLine();
Creat creat=new Creat();
creat.creatLinklist(s);
}
}
控制台输入:12345
输出:5
4
3
2
1
看到输出结果,大家就会知道头插法会改变数据输入顺序。在严格要求数据顺序不变时,可以用尾插法。
尾插法:新来的节点插入到当前节点末尾处。
package singleLinklistReverse_2;
import singleLinklistReverse.Reverse;
public class Creat {
//定义节点类
public class Lnode{
int data;
Lnode next;
// public Lnode(int d){
// this.data=d;
// }
}
//定义链表类
public class linkList{
}
/**
* 采用尾插法来建立单链表
* @param s 接收来自控制台输入的字符串
*/
public void creatLinklist(String s){
Lnode first=new Lnode();
first.next=null;
Lnode r=first;
for(int i=0;i<s.length();i++){
Lnode lnode=new Lnode();
lnode.data=s.charAt(i)-'0';
r.next=lnode;
r=lnode;
}
r.next=null;
Lnode p=first.next;
while(p!=null){
System.out.println(p.data);
p=p.next;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner=new Scanner(System.in);
String s=scanner.nextLine();
Creat creat=new Creat();
creat.creatLinklist(s);
}
}
结果:
12345
1
2
3
4
5
显然尾插法稳定性更好。