public class Node {
public int data;
public Node next;
public Node() {
}
public Node(int data) {
this.data = data;
}
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
//头结点
public static Node head;
/**
* 向链表中添加数据
*
* @param value
*/
public static void addData(int value) {
//初始化要加入的节点
Node newNode = new Node(value);
//临时节点
Node temp = head;
//找到尾节点
while (temp.next != null) {
temp = temp.next;
}
//包含了head.next == null 的情况
temp.next = newNode;
}
/**
* 遍历链表
*
* @param head
*/
public static void traverse(Node head) {
//临时节点
Node temp = head.next;
while (temp != null) {
System.out.println(temp.data);
temp = temp.next;
}
}
/**
* 插入节点
*
* @param head
* @param index 要插入的位置
* @param value
*/
public static void inserNode(Node head, int index, int value) {
//首先判断指定位置是否合法 (index < 1 或者 index > 链表长度 + 1)
if (index < 1 || index > linkListLength(head) + 1) {
System.out.println("插入位置不合法");
return;
}
//临时节点
Node temp = head;
//记录遍历的当前位置
int currentPos = 0;
//初始化要插入的节点
Node insertNode = new Node(value);
while (temp.next != null) {
//找到上一个节点的位置了
if ((index - 1) == currentPos) {
//temp标示的是上一个节点
//将原本由上一个节点的指向交由插入节点来指向
insertNode.next = temp.next;
//将上一个节点的指针域指向要插入的节点
temp.next = insertNode;
}
currentPos++;
temp = temp.next;
}
}
/**
* 获取链表的长度
*
* @param head
* @return
*/
public static int linkListLength(Node head) {
int length = 0;
//临时节点
Node temp = head.next;
while (temp != null) {
length++;
temp = temp.next;
}
return length;
}
/**
* 根据位置删除节点
*
* @param head
* @param index
*/
public static void deleteNode(Node head, int index) {
//判断位置是否合法
if (index < 1 || index > linkListLength(head) + 1) {
System.out.println("删除位置不合法");
return;
}
Node temp = head;
//记录遍历当前的位置
int currentPos = 0;
while (temp.next != null) {
if ((index - 1) == currentPos) {
//temp是上一个节点, temp.next是想删除的节点
//存储要删除的节点
Node deleteNode = temp.next;
temp.next = deleteNode.next;
//java会自动回收删除的节点
return;
}
currentPos++;
temp = temp.next;
}
}
/**
* 对链表排序 (使用冒泡)
*
* @param head
*/
public static void sortLinkList(Node head) {
Node currentNode;
Node nextNode;
for (currentNode = head.next; currentNode.next != null; currentNode = currentNode.next) {
for (nextNode = head.next; nextNode.next != null; nextNode = nextNode.next) {
if (nextNode.data > nextNode.next.data) {
int temp = nextNode.data;
nextNode.data = nextNode.next.data;
nextNode.next.data = temp;
}
}
}
}
/**
* 找到链表中倒数第k个节点(设置两个指针p1,p2, 让p2比p1快K个节点,同时向后遍历,当p2为空,则p1为倒数第k个节点位置)
*
* @param head
* @param k
* @return
*/
public static Node findKNode(Node head, int k) {
if (k < 1 || k > linkListLength(head))
return null;
Node p1 = head;
Node p2 = head;
//p2比p1快k个节点
for (int i = 0; i < k - 1; i++) {
p2 = p2.next;
}
//只要P2为null,则p1就是倒数第k个节点了
while (p2.next != null) {
p2 = p2.next;
p1 = p1.next;
}
return p1;
}
/**
* 删除链表重复数据
* @param head
*/
public static void deleteDuplecate(Node head) {
//临时节点
Node temp = head.next;
//当前节点 (首结点)的下一个节点
Node nextNode = temp.next;
while (temp != null) {
while (nextNode.next != null) {
if (nextNode.next.data == nextNode.data) {
//将下一个节点删除 (当前节点指向下下个节点)
nextNode.next = nextNode.next.next;
} else {
//继续下一个
nextNode = nextNode.next;
}
}
//下一轮比较
temp = temp.next;
}
}
/**
* 查询单链表的中间节点
* @param head
* @return
*/
public static Node searchMid(Node head) {
Node p1 = head;
Node p2 = head;
//一个走一步,一个走两步,直到为null,走一步的到达就是中间节点
while (p2 != null && p2.next!= null && p2.next.next != null) {
p1 = p1.next;
p2= p2.next.next;
}
return p1;
}
/**
* 递归从头到尾输出链表
* @param head
*/
public static void printListReversely(Node head) {
if (head != null) {
printListReversely(head.next);
System.out.println(head.data);
}
}
/**
* 实现链表翻转
* @param node
* @return
*/
public static Node reverseLinkList(Node node) {
Node prev;
if (node == null || node.next == null) {
prev = node;
} else {
Node tmp = reverseLinkList(node.next);
node.next.next = node;
node.next = null;
prev = tmp;
}
return prev;
}
链表翻转的思想是 递归到最后一个节点, 当做头结点 , 依然依次插入