直接上代码,思路什么的都在代码中
package com.jiyx.tesr.testLinked;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* auther: jiyx
* date: 2018/9/11.
*/
public class LinkedUtils {
/**
* 定义链表节点
*/
@AllArgsConstructor
@NoArgsConstructor
@Data
private static class Node {
private int value;
private Node next;
}
/**
* 创建链表
* @param len
* @return
*/
private static Node createNode(int len) {
if (len <= 0) {
return null;
} else {
return new Node(len, createNode(--len));
}
}
/**
* 这里是单向链表,所以如果翻转的时候是从中间节点开始的话,会丢失前面的节点
* 思路:获取当前节点,然后让当前节点指向他的头结点,然后他的下一个节点指向他
* 这个是自己第一时间想到的,是最麻烦的
*
* @param node
* @return
*/
public static Node reverse(Node node) {
Node curr = null;
Node next = null;
Node dNext = node;
Node pNext = null;
while (dNext != null) {
// 设置当前节点
curr = dNext;
// 获取下一位的节点
next = curr.getNext();
// 将当前的链表和已经反转的链表相连
curr.setNext(pNext);
if (next != null) {
// 获取链表的第三个节点,也就是需要进行下次翻转的开头
dNext = next.getNext();
} else {
// 将当前的链表和已经反转的链表相连,这里处理的是只剩一位
return curr;
}
// 翻转
next.setNext(curr);
// 记录已翻转的头结点
pNext = next;
}
return pNext;
}
/**
* 链表翻转2
* 思路:创建一个新的链表,将原链表由头开始,一个个放入新链表即可,贼简单
* @param node
* @return
*/
public static Node reverse2(Node node) {
// 新链表表头
Node newNodeHead = null;
// 当前节点
Node curr = node;
// 下一个节点
Node next = null;
while (curr != null) {
// 获取下一个节点
next = curr.getNext();
// 将当前节点放入新链表中
curr.setNext(newNodeHead);
// 重置new链表的表头
newNodeHead = curr;
// 下一位
curr = next;
}
return newNodeHead;
}
/**
* 链表翻转3
* 思路:移位,如1->2->3->4->5
* 第一次移位,变为2->1->3->4->5
* 第二次移位,变为3->2->1->4->5
* 以此类推,这个也是蛮简单的
* @param node
* @return
*/
public static Node reverse3(Node node) {
// 下一个节点
Node next = node.getNext();
// 头结点
Node head = node;
while (next != null) {
// node一直指向开始的头结点,设置他的下一个节点
node.setNext(next.getNext());
// 将跳过的节点设置到表头
next.setNext(head);
// 重置表头
head = next;
// 下一位
next = node.getNext();
}
return head;
}
/**
* 根据步长翻转,这个方法的思路是根据步长截取每段,然后进行翻转,然后拼接.单向链表,这个写起来感觉很麻烦
* @param node
* @param step
* @return
*/
public static Node reverse(Node node, int step) {
// 当前头结点,翻转之后的尾节点
Node currHead = null;
// 下一个头结点
Node nextHead = node;
// 当前结点,用于计算尾节点
Node curr = null;
// 上一个的尾节点
Node pTail = null;
// 这里设置为null是为了为node重新赋值
node = null;
while (nextHead != null) {
// 存储上步的尾节点,为下面使用
pTail = currHead;
curr = currHead = nextHead;
// 根据步长找到尾节点
for (int i = 0; i < step - 1; i++) {
if (curr.getNext() != null) {
curr = curr.getNext();
}
}
// 记录下一个步长开始位置
nextHead = curr.getNext();
// 将当前节点独立出来进行翻转
curr.setNext(null);
// 链表翻转,这里没用接收结果是因为,翻转完之后头变尾,尾变头
reverse(currHead);
if (pTail != null) {
// 由于单链表翻转丢失前端节点,所以这里在翻转完成之后再进行链表的连接
pTail.setNext(curr);
}
// 这里从新设定表头
if (node == null) {
node = curr;
}
}
return node;
}
}
网友评论