前些日子面试,面试官问我Java实现链表逆置,因为我写的用了两个变量操作,被怼的很难受。决定将Java链表好好总结一下。
一:链表介绍:
为了避免插入和删除的线性开销,就需要保证表可以不连续存储,否则表的每部分可能都需要整体移动。Java语言中包含一些普通数据结构的实现,这部分叫做Collections API.
Collections API位于java.util包中,collection接口要注意它扩展了Iterable接口,实现Iterable接口的集合必须提供一个称为iterator的方法,迭代器可以实现循环遍历。List接口继承了Collection接口。
线性时间删除表中的偶数:
public static void removeEvens(List<Integer> lst){
Iterator<Integer> itr=lst.iterator();
while(itr.hasNext()){
if(itr.next()%2==0)
itr.remove();
}
}
上面代码对ArrayList是二次的,但对LinkedList是线性的。
链表逆置:
定义结点:
public class Node {
private int value;
private Node nextNode;
public Node(int value){
this.value=value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getNextNode(){
return nextNode;
}
public void setNextNode(Node nextNode) {
this.nextNode = nextNode;
}
}
1.递归逆置单链表
//递归逆置
public static Node reverLink(Node head){
//递归的判断条件
if( head==null || head.getNextNode()==null ){
return head;
}
//一直入栈
//Node reverNode=reverLink(head.nextNode);
Node reverNode=reverLink(head.getNextNode());
//递归到栈顶返回了head,并且出栈
//head.nextNode.nextNode=head;
head.getNextNode().setNextNode(head);
// head.nextNode=null;
head.setNextNode(null);
return reverNode;
}
2.非递归逆置
private static Node revertLinkByPoint(Node head) {
if (null == head) {
return head;
}
Node pre = head;
Node cur = head.getNextNode();
Node next;
while (cur !=null) {
//断之前先找到原始的下一个节点
next = cur.getNextNode();
//逆序连接
cur.setNextNode(pre);
//两个节点同时滑动
pre = cur;
cur = next;
}
//将原链表的头节点的下一个节点置为null,再将反转后的头节点赋给head
head.setNextNode(null);
head = pre;
return head;
}
定义一个链表,调用逆置方法·
public class Test {
public static void main(String[] args) {
//带有头结点
Node head = new Node(0);
Node tmp = null; // 保存临时变量
Node cur = null; // 始终指向末尾节点
//构造一个长度为10的链表,保存头节点对象head
//利用尾插入法
for (int i = 1; i < 10; i++) {
tmp = new Node(i);
if (1 == i) {
head.setNextNode(tmp);
} else {
cur.setNextNode(tmp);
}
cur = tmp;
}
//打印反转前的链表
Node h = head;
while (h !=null) {
System.out.print(h.getValue() + " ");
h = h.getNextNode();
}
//调用反转方法
head = reverLinklist.reverLink(head);
System.out.println("\n*******************");
//打印反转后的结果
while (head !=null) {
System.out.print(head.getValue() + " ");
head = head.getNextNode();
}
}
}