面试恶补校园知识系列----双向链表Java实现

Java代码实现:

package org.megustas.personal.algorithm;

/**
 * 双向链表实现
 *
 * @author yuzy
 * @version 1.0
 * @date 2019/12/01 15:48
 */

public class DoubleLinkedList<T> {
    // 节点对应实体
    private class OwnNode<T>{
        public OwnNode preNode;
        public OwnNode nextNode;
        public T value;

        public OwnNode(OwnNode preNode, OwnNode nextNode, T value) {
            this.preNode = preNode;
            this.nextNode = nextNode;
            this.value = value;
        }
    }
    // 表头
    private OwnNode<T> headNode;
    // 节点个数
    private int nCount;
    // 构造方法
    public DoubleLinkedList() {
        // 创建表头
        headNode = new OwnNode<>(null,null,null);
        // 赋值表头的前驱与后继节点都是自己
        headNode.preNode = headNode.nextNode = headNode;
        // 初始化链表长度为0
        nCount = 0;
    }

    // 获取节点数量
    public int getNodeCount(){
        return nCount;
    }
    // 获取链表是否为空
    public boolean isLinkedEmpty(){
        return nCount == 0;
    }
    // 获取下标位置的节点
    private OwnNode<T> getNode(int index){
        if(index < 0 || index >= nCount){
            throw new IndexOutOfBoundsException();
        }
        // 正向查找
        if(index <= nCount/2){
            OwnNode<T> node = headNode.nextNode;
            for (int i = 0; i < index; i++) {
                node = node.nextNode;
            }
            return node;
        }
        // 反向查找
        OwnNode<T> rNode = headNode.preNode;
        int rIndex = nCount - index - 1;
        for (int j = 0; j < rIndex; j++) {
            rNode = rNode.preNode;
        }
        return rNode;
    }

    // 获取对应节点的值
    public T getValue(int index){
        return getNode(index).value;
    }

    // 获取第一个节点的值
    public T getFirst(){
        return getNode(0).value;
    }
    // 获取最后一个节点的值
    public T getLast(){
        return getNode(nCount - 1).value;
    }
    // 将节点插入到index位置 在节点index插入值
    public void insertNode(int index,T t){
        if(index == 0){
            OwnNode<T> node = new OwnNode<>(headNode, headNode.nextNode, t);
            headNode.nextNode.preNode = node;
            headNode.nextNode = node;
            nCount++;
            return;
        }
        OwnNode<T> currNode = getNode(index);
        OwnNode<T> newNode = new OwnNode<>(currNode.preNode, currNode, t);
        currNode.preNode.nextNode = newNode;
        currNode.preNode = newNode;
        nCount++;
        return;
    }
    // 插入节点到index 0
    public void insertFirst(T t){
        insertNode(0,t);
    }
    // 插入节点到链表末尾
    public void insertLast(T t){
        OwnNode<T> lastNode = new OwnNode<>(headNode.nextNode, headNode, t);
        headNode.preNode.nextNode = lastNode;
        headNode.preNode = lastNode;
        nCount++;
    }
    // 删除对应节点
    public void deleteNode(int index){
        OwnNode<T> node = getNode(index);
        node.preNode.nextNode = node.nextNode;
        node.nextNode.preNode = node.preNode;
        node = null;
        nCount--;
    }
    // 删除第一个节点
    public void deleteFirst(){
        deleteNode(0);
    }
    // 删除最后一个节点
    public void deleteLast(){
        OwnNode<T> lastNode = getNode(nCount - 1);
        lastNode.preNode.nextNode = headNode;
        headNode.preNode = lastNode.preNode;
        lastNode = null;
        nCount--;
    }
}

测试用例:

package org.megustas.personal.algorithm;

/**
 * 测试自定义双向链表类
 *
 * @author yuzy
 * @version 1.0
 * @date 2019/12/01 17:19
 */

public class OwnLinkedListTest {
   
    // 双向链表操作int数据
    private static void int_test() {
        int[] iarr = {10, 20, 30, 40};

        System.out.println("\n----int_test----");
        // 创建双向链表
        DoubleLinkedList<Integer> dlink = new DoubleLinkedList<Integer>();

        dlink.insertNode(0, 20);    // 将 20 插入到第一个位置
        dlink.insertLast(10);    // 将 10 追加到链表末尾
        dlink.insertFirst(30);    // 将 30 插入到第一个位置

        // 双向链表是否为空
        System.out.printf("isEmpty()=%b\n", dlink.isLinkedEmpty());
        // 双向链表的大小
        System.out.printf("size()=%d\n", dlink.getNodeCount());

        // 打印出全部的节点
        for (int i=0; i<dlink.getNodeCount(); i++)
            System.out.println("dlink("+i+")="+ dlink.getValue(i));
    }


    private static void string_test() {
        String[] sarr = {"ten", "twenty", "thirty", "forty"};

        System.out.println("\n----string_test----");
        // 创建双向链表
        DoubleLinkedList<String> dlink = new DoubleLinkedList<String>();

        dlink.insertNode(0, sarr[1]);    // 将 sarr中第2个元素 插入到第一个位置
        dlink.insertLast(sarr[0]);    // 将 sarr中第1个元素 追加到链表末尾
        dlink.insertFirst(sarr[2]);    // 将 sarr中第3个元素 插入到第一个位置

        // 双向链表是否为空
        System.out.printf("isEmpty()=%b\n", dlink.isLinkedEmpty());
        // 双向链表的大小
        System.out.printf("size()=%d\n", dlink.getNodeCount());

        // 打印出全部的节点
        for (int i=0; i<dlink.getNodeCount(); i++)
            System.out.println("dlink("+i+")="+ dlink.getValue(i));
    }


    // 内部类
    private static class Student {
        private int id;
        private String name;

        public Student(int id, String name) {
            this.id = id;
            this.name = name;
        }

        @Override
        public String toString() {
            return "["+id+", "+name+"]";
        }
    }

    private static Student[] students = new Student[]{
            new Student(10, "sky"),
            new Student(20, "jody"),
            new Student(30, "vic"),
            new Student(40, "dan"),
    };

    private static void object_test() {
        System.out.println("\n----object_test----");
        // 创建双向链表
        DoubleLinkedList<Student> dlink = new DoubleLinkedList<Student>();

        dlink.insertNode(0, students[1]);    // 将 students中第2个元素 插入到第一个位置
        dlink.insertLast(students[0]);    // 将 students中第1个元素 追加到链表末尾
        dlink.insertFirst(students[2]);    // 将 students中第3个元素 插入到第一个位置

        // 双向链表是否为空
        System.out.printf("isEmpty()=%b\n", dlink.isLinkedEmpty());
        // 双向链表的大小
        System.out.printf("size()=%d\n", dlink.getNodeCount());

        // 打印出全部的节点
        for (int i=0; i<dlink.getNodeCount(); i++) {
            System.out.println("dlink("+i+")="+ dlink.getValue(i));
        }
    }


    public static void main(String[] args) {
        int_test();        // 演示向双向链表操作“int数据”。
        string_test();    // 演示向双向链表操作“字符串数据”。
        object_test();    // 演示向双向链表操作“对象”。
    }
}

实现是参考一篇博客来着,测试用例更是直接复制  =-=! 毕竟工作也很多copy paste是吧。。。

这里贴参考文章地址:https://www.cnblogs.com/skywang12345/p/3561803.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值