通过指针将一组零散的内存块串联在一起。
一:有趣的问题
1.LRU算法
按照时间有序的链表
如果存在链表中,删除,然后插入到头部
如果不存在,插入尾部
如果没有空间了,删除最后一个位置。
2.约瑟夫问题
这里的逻辑是,先形成一个环。
然后,p开始数数,之后1,2保留,3进行删除。
package com.jun.algorithm.foundation.main;
import com.jun.algorithm.common.Node;
import org.junit.Test;
/**
* 约瑟夫环的问题
*
* @author caojun
*/
public class JosefCircle {
public void loop(int n) {
int k = 3;
// 1.先产生约瑟夫环
// 产生一个空的头结点
Node head = new Node();
Node current = head;
for (int i = 1; i <= n; i++) {
Node node = new Node(i);
current.setNext(node);
current = node;
}
current.setNext(head.getNext());
// 2.进行出局
Node p = head.getNext();
while (p.getNext() != p) {
// 进行k-1循环,到要删除的那个点的前一个点
for (int i = 1; i < k - 1; i++) {
p = p.getNext();
}
// 删除后一个节点
System.out.println("删除的节点是=>" + p.getNext().getVal());
p.setNext(p.getNext().getNext());
p=p.getNext();
}
System.out.println("最后剩下的点是=>"+p.getVal());
}
/**
* 测试
*/
@Test
public void test() {
loop(4);
}
}
二:链表
1.单链表增删改查
package com.jun.algorithm.foundation.main;
import com.jun.algorithm.common.Node;
/**
* 单链表程序
*
* @author caojun
*/
public class SingleLinkedList {
private Node head;
private int size = 0;
/**
* 将节点插入头节点
*
* @param data 插入的数据
*/
private void insertHead(int data) {
Node node = new Node(data);
node.setNext(head);
head = node;
}
/**
* 在某个位置插入数据
*
* @param data 要插入的数据
* @param position 插入的位置
*/
private void insertNth(int data, int position) {
if (position == 0) {
insertHead(data);
} else {
Node current = head;
// 遍历
for (int i = 1; i < position; i++) {
current = current.getNext();
}
// 先让后面的链保证不断,然后让当前的点关联上
Node node = new Node();
node.setNext(current.getNext());
current.setNext(node);
}
}
/**
* 删除头节点
*/
private void deleteHead() {
head = head.getNext();
}
/**
* 删除第几个节点
*/
private void deleteNth(int position) {
if (position == 0) {
deleteHead();
} else {
Node current = head;
for (int i = 1; i < position; i++) {
current = current.getNext();
}
current.setNext(current.getNext().getNext());
}
}
/**
* 打印链表
*/
public void print() {
Node current = head;
while (current != null) {
System.out.println(current.getVal() + "");
current = current.getNext();
}
System.out.println();
}
}
2.双向链表
package com.jun.algorithm.foundation.main; import com.jun.algorithm.common.DoubleNode; import org.junit.Test; /** * 双向链表 * * @author caojun */ public class DoubleLinkedList { private DoubleNode head; private DoubleNode tail; /** * 插入头结点 * * @param data 将要插入的数据 */ public void insertHead(int data) { DoubleNode doubleNode = new DoubleNode(data); if (head == null) { tail = doubleNode; } else { head.setPre(doubleNode); doubleNode.setNext(head); } // 新的点赋值给头结点 head = doubleNode; } /** * 将数据插入到链表的某个位置 * * @param data 数据 * @param position 位置 */ public void insertNth(int data, int position) { if (position == 0) { insertHead(data); } else { DoubleNode current = head; for (int i = 1; i < position; i++) { current = current.getNext(); } // 开始创建新的节点,然后连接 DoubleNode node = new DoubleNode(data); current.getNext().setPre(node); node.setNext(current.getNext()); node.setPre(current); current.setNext(node); } } /** * 从头部往后进行遍历 */ public void printNext() { System.out.println("进行头部遍历"); DoubleNode current = head; while (current != null) { System.out.print(current.getVal()+ " "); current = current.getNext(); } System.out.println(); } /** * 从尾部开始往前进行遍历 */ public void printPre() { System.out.println("进行尾部遍历"); DoubleNode current = tail; while (current != null) { System.out.print(current.getVal() + " "); current = current.getPre(); } System.out.println(); } @Test public void test() { // 组装链表 DoubleNode node1 = new DoubleNode(2); DoubleNode node2 = new DoubleNode(3); node1.setNext(node2); node2.setPre(node1); head = node1; tail = node2; // 插入头节点测试 insertHead(8); // print(); // 将数据插入到某个位置 insertNth(89, 2); printNext(); printPre(); } }
posted on
浙公网安备 33010602011771号