- 获取链表中间结点
- 获取链表倒数第 k 个节点
package linkedlist;
/**
* Created by lenovo on 2018/4/2.
*/
public class MyLinkedList<T> {
private Node<T> header;
private int size;
public MyLinkedList() {
this.header = new Node<>(null); // 链表头不放数据
}
public Node<T> getHeader() {
return header;
}
public boolean insert(T data) {
Node tmp = header;
while (true) {
if (tmp.next == null) {
tmp.next = new Node(data);
size++;
break;
}
tmp = tmp.next;
}
return true;
}
public boolean delete(T data) {
Node tmp = header.next;
if (tmp != null && tmp.data.equals(data)) {
header.next = tmp.next;
size--;
return true;
}
while (tmp != null) {
Node previous = tmp;
tmp = tmp.next;
Node next = null;
if (tmp != null) {
next = tmp.next;
if (tmp.data.equals(data)) {
previous.next = next;
size--;
return true;
}
} else {
return false;
}
}
return false;
}
public boolean update(T olddata, T newdata) {
Node tmp = header.next;
while (tmp != null) {
if (tmp.data.equals(olddata)) {
tmp.data = newdata;
return true;
}
tmp = tmp.next;
}
return true;
}
public boolean query(T data) {
Node tmp = header.next;
while (tmp != null) {
if (tmp.data.equals(data)) {
return true;
}
tmp = tmp.next;
}
return false;
}
public void deleteDuplicateNodes() {
Node outer = header.next;
while (outer != null) {
Node inner = outer;
Node cur = inner.next;
while (cur != null) {
if (outer.data == cur.data) {
inner.next = cur.next;
cur = cur.next;
size--;
} else {
inner = cur;
cur = cur.next;
}
}
outer = outer.next;
}
}
/**
* 反转链表
*/
public void reverseLinkedList() {
Node cur = header.next;
Node pre = null;
while (cur != null) {
Node next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
header.next = pre;
}
public void print() {
Node cur = header.next;
while (cur != null) {
System.out.print(cur.data + "->");
cur = cur.next;
}
System.out.println();
}
/**
* 未知链表长度:获取链表倒数第 k 个节点(双指针法,相差 k-1)
* 已知链表长度length:前进 length-k+1 个节点
*
* @param k
* @return
*/
public Node<T> getEndK(int k) {
if (size < k) {
return null;
}
Node first = header.next;
Node second = first;
for (int i = 0; i < k - 1; i++) {
// 走 k-1 步, first 和 second 相差 k-1 步,当 second.next 为空时。first 为倒数第 k 个节点
second = second.next;
}
while (second.next != null) {
first = first.next;
second = second.next;
}
return first;
}
/**
* 获取链表中间节点,双数,打印中间两个节点
* 双指针法,一快一慢
*
* @param
*/
public void printMidNode() {
Node first = header;
Node second = header;
if (second.next == null) {
// 空链表
print();
return;
}
// head 1 2 3 4 5
// first =1 second = 2
// first = 2 second = 4
// first = 3 second = null;
// head 1 2 3 4
// first =1 second = 2
// first =2 second= 4
while (true) {
first = first.next; //2 3 4
second = second.next.next;//3 5
if (second != null && second.next == null) {
// 偶数
System.out.println(first.data + " & " + first.next.data);
return;
} else if (second == null) {
// 奇数
System.out.println(first.data);
return;
}
}
}
/**
* 判断单链表是否有环(双指针法 , n%节点数 = 2*n%节点数 , n为迭代次数 ,如果有环,最多迭代次数 == 节点数时,就会相遇)
*
* @return
*/
public boolean hasLoop() {
Node first = header.next;
Node second = header.next;
while (second != null && second.next != null && second.next.next != null) {
first = first.next;
second = second.next.next;
if (second == first) {
return true;
}
}
return false;
}
class Node<T> {
T data;
Node<T> next;
public Node(T data) {
this.data = data;
}
}
}