通过指针将一组零散的内存块串联在一起。

 

一:有趣的问题

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 2022-03-13 21:04  曹军  阅读(32)  评论(0编辑  收藏  举报