1.單鏈表LRU算法
package linked.singlelist;
import java.util.Scanner;
/**
* 基於單鏈表LRU算法(java)
*/
public class LRUBaseLinkedList<T> {
/**
* 默認鏈表容量
*/
private final static Integer DEFAULT_CAPACITY = 10;
/**
* 頭結點
*/
private SNode<T> headNode;
/**
* 鏈表長度
*/
private Integer length;
/**
* 鏈表容量
*/
private Integer capacity;
public LRUBaseLinkedList() {
this.headNode = new SNode<>();
this.capacity = DEFAULT_CAPACITY;
this.length = 0;
}
public LRUBaseLinkedList(Integer capacity) {
this.headNode = new SNode<>();
this.capacity = capacity;
this.length = 0;
}
public void add(T data) {
SNode preNode = findPreNode(data);
// 鏈表中存在,刪除原數據,再插入到鏈表的頭部
if (preNode != null) {
deleteElemOptim(preNode);
intsertElemAtBegin(data);
} else {
if (length >= this.capacity) {
//刪除尾結點
deleteElemAtEnd();
}
intsertElemAtBegin(data);
}
}
/**
* 刪除preNode結點下一個元素
*
* @param preNode
*/
private void deleteElemOptim(SNode preNode) {
SNode temp = preNode.getNext();
preNode.setNext(temp.getNext());
temp = null;
length--;
}
/**
* 鏈表頭部插入節點
*
* @param data
*/
private void intsertElemAtBegin(T data) {
SNode next = headNode.getNext();
headNode.setNext(new SNode(data, next));
length++;
}
/**
* 獲取查找到元素的前一個結點
*
* @param data
* @return
*/
private SNode findPreNode(T data) {
SNode node = headNode;
while (node.getNext() != null) {
if (data.equals(node.getNext().getElement())) {
return node;
}
node = node.getNext();
}
return null;
}
/**
* 刪除尾結點
*/
private void deleteElemAtEnd() {
SNode ptr = headNode;
// 空鏈表直接返回
if (ptr.getNext() == null) {
return;
}
// 倒數第二個結點
while (ptr.getNext().getNext() != null) {
ptr = ptr.getNext();
}
SNode tmp = ptr.getNext();
ptr.setNext(null);
tmp = null;
length--;
}
private void printAll() {
SNode node = headNode.getNext();
while (node != null) {
System.out.print(node.getElement() + ",");
node = node.getNext();
}
System.out.println();
}
public class SNode<T> {
private T element;
private SNode next;
public SNode(T element) {
this.element = element;
}
public SNode(T element, SNode next) {
this.element = element;
this.next = next;
}
public SNode() {
this.next = null;
}
public T getElement() {
return element;
}
public void setElement(T element) {
this.element = element;
}
public SNode getNext() {
return next;
}
public void setNext(SNode next) {
this.next = next;
}
}
public static void main(String[] args) {
LRUBaseLinkedList list = new LRUBaseLinkedList();
Scanner sc = new Scanner(System.in);
while (true) {
list.add(sc.nextInt());
list.printAll();
}
}
}
2.常見鏈表操作
* 1) 單鏈表反轉
* 2) 鏈表中環的檢測
* 3) 兩個有序的鏈表合併
* 4) 刪除鏈表倒數第n個結點
* 5) 求鏈表的中間結點
package linkedlist;
public class LinkedListAlgo {
/**
* day07
* 1) 單鏈表反轉
* 2) 鏈表中環的檢測
* 3) 兩個有序的鏈表合併
* 4) 刪除鏈表倒數第n個結點
* 5) 求鏈表的中間結點
*
* Author: Zheng
*/
// 單鏈表反轉
public static Node reverse(Node list) {
Node headNode = null;
Node previousNode = null;
Node currentNode = list;
while (currentNode != null) {
Node nextNode = currentNode.next;
if (nextNode == null) {
headNode = currentNode;
}
currentNode.next = previousNode;
previousNode = currentNode;
currentNode = nextNode;
}
return headNode;
}
// 檢測環
public static boolean checkCircle(Node list) {
if (list == null) return false;
Node fast = list.next;
Node slow = list;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (slow == fast) return true;
}
return false;
}
// 有序鏈表合併
public static Node mergeSortedLists(Node la, Node lb) {
if (la == null) return lb;
if (lb == null) return la;
Node p = la;
Node q = lb;
Node head;
if (p.data < q.data) {
head = p;
p = p.next;
} else {
head = q;
q = q.next;
}
Node r = head;
while (p != null && q != null) {
if (p.data < q.data) {
r.next = p;
p = p.next;
} else {
r.next = q;
q = q.next;
}
r = r.next;
}
if (p != null) {
r.next = p;
} else {
r.next = q;
}
return head;
}
// 刪除倒數第K個結點
public static Node deleteLastKth(Node list, int k) {
Node fast = list;
int i = 1;
while (fast != null && i < k) {
fast = fast.next;
++i;
}
if (fast == null) return list;
Node slow = list;
Node prev = null;
while (fast.next != null) {
fast = fast.next;
prev = slow;
slow = slow.next;
}
if (prev == null) {
list = list.next;
} else {
prev.next = prev.next.next;
}
return list;
}
// 求中間結點
public static Node findMiddleNode(Node list) {
if (list == null) return null;
Node fast = list;
Node slow = list;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
public static void printAll(Node list) {
Node p = list;
while (p != null) {
System.out.print(p.data + " ");
p = p.next;
}
System.out.println();
}
public static Node createNode(int value) {
return new Node(value, null);
}
public static class Node {
private int data;
private Node next;
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
public int getData() {
return data;
}
}
}
3.單鏈表結構常見操作及判斷字符串是否是迴文
package linkedlist;
/**
* 1)單鏈表的插入、刪除、查找操作;
* 2)鏈表中存儲的是int類型的數據;
*
* Author:Zheng
*/
public class SinglyLinkedList {
private Node head = null;
public Node findByValue(int value) {
Node p = head;
while (p != null && p.data != value) {
p = p.next;
}
return p;
}
public Node findByIndex(int index) {
Node p = head;
int pos = 0;
while (p != null && pos != index) {
p = p.next;
++pos;
}
return p;
}
//無頭結點
//表頭部插入
//這種操作將於輸入的順序相反,逆序
public void insertToHead(int value) {
Node newNode = new Node(value, null);
insertToHead(newNode);
}
public void insertToHead(Node newNode) {
if (head == null) {
head = newNode;
} else {
newNode.next = head;
head = newNode;
}
}
//順序插入
//鏈表尾部插入
public void insertTail(int value){
Node newNode = new Node(value, null);
//空鏈表,可以插入新節點作爲head,也可以不操作
if (head == null){
head = newNode;
}else{
Node q = head;
while(q.next != null){
q = q.next;
}
newNode.next = q.next;
q.next = newNode;
}
}
public void insertAfter(Node p, int value) {
Node newNode = new Node(value, null);
insertAfter(p, newNode);
}
public void insertAfter(Node p, Node newNode) {
if (p == null) return;
newNode.next = p.next;
p.next = newNode;
}
public void insertBefore(Node p, int value) {
Node newNode = new Node(value, null);
insertBefore(p, newNode);
}
public void insertBefore(Node p, Node newNode) {
if (p == null) return;
if (head == p) {
insertToHead(newNode);
return;
}
Node q = head;
while (q != null && q.next != p) {
q = q.next;
}
if (q == null) {
return;
}
newNode.next = p;
q.next = newNode;
}
public void deleteByNode(Node p) {
if (p == null || head == null) return;
if (p == head) {
head = head.next;
return;
}
Node q = head;
while (q != null && q.next != p) {
q = q.next;
}
if (q == null) {
return;
}
q.next = q.next.next;
}
public void deleteByValue(int value) {
if (head == null) return;
Node p = head;
Node q = null;
while (p != null && p.data != value) {
q = p;
p = p.next;
}
if (p == null) return;
if (q == null) {
head = head.next;
} else {
q.next = q.next.next;
}
// 可重複刪除指定value的代碼
/*
if (head != null && head.data == value) {
head = head.next;
}
Node pNode = head;
while (pNode != null) {
if (pNode.next.data == data) {
pNode.next = pNode.next.next;
continue;
}
pNode = pNode.next;
}
*/
}
public void printAll() {
Node p = head;
while (p != null) {
System.out.print(p.data + " ");
p = p.next;
}
System.out.println();
}
//判斷true or false
public boolean TFResult(Node left, Node right){
Node l = left;
Node r = right;
System.out.println("left_:"+l.data);
System.out.println("right_:"+r.data);
while(l != null && r != null){
if (l.data == r.data){
l = l.next;
r = r.next;
continue;
}else{
break;
}
}
System.out.println("什麼結果");
if (l==null && r==null){
System.out.println("什麼結果");
return true;
}else{
return false;
}
}
// 判斷是否爲迴文
public boolean palindrome(){
if (head == null){
return false;
}else{
System.out.println("開始執行找到中間節點");
Node p = head;
Node q = head;
if (p.next == null){
System.out.println("只有一個元素");
return true;
}
while( q.next != null && q.next.next != null){
p = p.next;
q = q.next.next;
}
System.out.println("中間節點" + p.data);
System.out.println("開始執行奇數節點的迴文判斷");
Node leftLink = null;
Node rightLink = null;
if(q.next == null){
// p 一定爲整個鏈表的中點,且節點數目爲奇數
rightLink = p.next;
leftLink = inverseLinkList(p).next;
System.out.println("左邊第一個節點"+leftLink.data);
System.out.println("右邊第一個節點"+rightLink.data);
}else{
//p q 均爲中點
rightLink = p.next;
leftLink = inverseLinkList(p);
}
return TFResult(leftLink, rightLink);
}
}
//帶結點的鏈表翻轉
public Node inverseLinkList_head(Node p){
// Head 爲新建的一個頭結點
Node Head = new Node(9999,null);
// p 爲原來整個鏈表的頭結點,現在Head指向 整個鏈表
Head.next = p;
/*
帶頭結點的鏈表翻轉等價於
從第二個元素開始重新頭插法建立鏈表
*/
Node Cur = p.next;
p.next = null;
Node next = null;
while(Cur != null){
next = Cur.next;
Cur.next = Head.next;
Head.next = Cur;
System.out.println("first " + Head.data);
Cur = next;
}
// 返回左半部分的中點之前的那個節點
// 從此處開始同步像兩邊比較
return Head;
}
//無頭結點的鏈表翻轉
public Node inverseLinkList(Node p){
Node pre = null;
Node r = head;
System.out.println("z---" + r.data);
Node next= null;
while(r !=p){
next = r.next;
r.next = pre;
pre = r;
r = next;
}
r.next = pre;
// 返回左半部分的中點之前的那個節點
// 從此處開始同步像兩邊比較
return r;
}
public static Node createNode(int value) {
return new Node(value, null);
}
public static class Node {
private int data;
private Node next;
public Node(int data, Node next) {
this.data = data;
this.next = next;
}
public int getData() {
return data;
}
}
public static void main(String[]args){
SinglyLinkedList link = new SinglyLinkedList();
System.out.println("hello");
//int data[] = {1};
//int data[] = {1,2};
//int data[] = {1,2,3,1};
//int data[] = {1,2,5};
//int data[] = {1,2,2,1};
// int data[] = {1,2,5,2,1};
int data[] = {1,2,5,3,1};
for(int i =0; i < data.length; i++){
//link.insertToHead(data[i]);
link.insertTail(data[i]);
}
// link.printAll();
// Node p = link.inverseLinkList_head(link.head);
// while(p != null){
// System.out.println("aa"+p.data);
// p = p.next;
// }
System.out.println("打印原始:");
link.printAll();
if (link.palindrome()){
System.out.println("迴文");
}else{
System.out.println("不是迴文");
}
}
}