- 单链表反转
- 链表中环的检测
- 两个有序链表合并
- 删除链表中倒数第n个结点
- 求链表的中间结点
封装的Node信息如下:后面代码不再给出
package cn.wangbo.list;
/*
* 这是链表类,
* 封装了链表节点信息
* */
public class Node<T> {
T val; //值
Node next; //next指针
public Node() {
}
public Node(T val, Node next) {
this.val = val;
this.next = next;
}
}
单链表反转
单链表反转,只需要将每个结点的next指针指向其前驱结点。这个过程中,为了避免断链,我们需要新建三个结点记录当前结点、当前结点的前驱结点、当前结点的下一结点
- 核心代码如下:
Node<String> preNode = new Node<String>();
Node<String> curNode = list;//list是链表头指针
Node<String> nextNode = new Node<String>();
//反转指针
while (curNode.next != null){
nextNode = curNode.next;
curNode.next = preNode;
preNode = curNode;
curNode = nextNode;
}
curNode.next = preNode;
链表中环的检测
这里可以采用快慢指针法。快指针每次走两步、慢指针每次走一步。如果快慢指针相遇,则说明有环,否则如果快指针走到终点(null)则说明无环。
- 核心代码如下
public static boolean ringTest(Node node){
if (node == null){
return false;
}
Node slowNode = node;
Node fastNode = node.next;
while (fastNode.next != null && fastNode != null){
slowNode = slowNode.next;
fastNode = fastNode.next.next;
if (fastNode == null){
return false;
}else if (fastNode == slowNode){
return true;
}
}
return false;
}
两个有序链表合并
两个有序链表合并思路并不复杂,但是千万要注意最后不要忘记指向剩下没有指向过的结点。
- 核心代码如下:
static Node Merge(Node<Integer> node1,Node<Integer> node2){
Node pNode = new Node();
Node<Integer> node = pNode;
if (node1 == null) return node2;
else if (node2 == null) return node1;
while (node1 != null && node2 != null){
if (node1.val <= node2.val){
node.next = node1;
node1 = node1.next;
}else{
node.next = node2;
node2 = node2.next;
}
node = node.next;
}
if (node1 == null){
node.next = node2;
}
else if (node2 == null){
node.next = node1;
}
return pNode.next;
}
删除链表中倒数第n个结点
如果采用两次遍历的话自然非常简单,但是如果要求只遍历一次怎么做呢?首先用两个指针指向head结点,把第一个指针指向第n个结点,然后同时将两个指针往后一步步移动,当第一个指针的next指向null的时候,第二个指针指向第倒数n-1个结点,sNode.next = sNode.next.next即完成删除
- 核心代码如下:
public static Node<Integer> delete(Node<Integer> head,int n){
Node<Integer> fNode = head;
Node<Integer> sNode = head;
for (int i = 0;i < n;i++){
fNode = fNode.next;
}
//如果链表长度为n
if (fNode == null){
head = head.next;
return head;
}
while (fNode.next != null){
sNode = sNode.next;
fNode = fNode.next;
}
sNode.next = sNode.next.next;
return head;
}
求链表的中间结点
这里同样是采用快慢指针法。快指针每次走两步,慢指针每次走一步,当快指针走完整个链表的时候,慢指针刚好走到链表的中间节点
- 核心代码如下:
public static Node<Integer> getMid(Node<Integer> node){
Node<Integer> fastNode = node;
Node<Integer> slowNode = node;
while (fastNode != null && fastNode.next != null){
fastNode = fastNode.next.next;
slowNode = slowNode.next;
}
return slowNode;
}