面試惡補校園知識系列----雙向鏈表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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章