欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java数组实现双向链表

程序员文章站 2024-03-22 10:59:22
...
package com.luna.util;

/**
 * 定义双向链表结构对象:考虑到双向链表可以存储基本数据类型、字符串、对象故节点封装用泛型参数;考虑到双向链表数据结构的隐私和安全性,
 * 链表的所有属性和节点内部定义类均用private修饰;数组的特点是:数据是一次性开辟连续的存储空间;随机访问速度快;双向链表:双向链表
 * (双链表)是链表的一种。和单链表一样,双链表也是由节点组成,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双
 * 向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
 * 1.定义双向链表的两个私有基本属性:链表头结点和链表的容量;
 * 2.用私有内部类定义双向链表的节点结构;
 * 3.定义链表初始化构造函数;
 * 4.定义链表的基本操作:获取链表节点数方法;判断链表是否为空方法;获取指定位置的节点对象;获取指定位置的节点值;获取第一个节点的值;
 * 获取最后一个节点的值;将节点插入到指定位置;将节点插入到第一个节点处;将节点追加到链表末尾;删除给定位置的链表节点;删除第一个节点;
 * 删除最后一个节点。
 *
 */
public class ArryToDoubleLinked<T> {

    // 定义链表表头节点
    private DNode<T> mHead;
    // 链表节点个数
    private int mCount;

    // 双向链表结构体
    private class DNode<T> {
        public DNode prev;
        public DNode next;
        public T value;

        public DNode(T value, DNode prev, DNode next) {
            this.value = value;
            this.prev = prev;
            this.next = next;
        }
    }

    // 构造函数
    public ArryToDoubleLinked() {
        // 初始化链表初始信息节点
        mHead = new DNode<T>(null, null, null);
        mHead.prev = mHead.next = mHead;
        // 初始化链表节点数为0
        mCount = 0;
    }

    // 返回节点数目
    public int size() {
        return mCount;
    }

    // 返回链表是否为空
    public boolean isEmpty() {
        return mCount == 0;
    }

    // 获取第index位置的节点
    private DNode<T> getNode(int index) {
        if (index < 0 || index >= mCount)
            throw new IndexOutOfBoundsException();
        // 如果待取的数据节点小于等于链表长度的一半时正向查找
        if (index <= mCount / 2) {
            DNode<T> node = mHead.next;
            for (int i = 0; i < index; i++)
                node = node.next;
            return node;
        }

        // 反向查找
        DNode<T> rnode = mHead.prev;
        int rindex = mCount - index - 1;
        for (int j = 0; j < rindex; j++)
            rnode = rnode.prev;
        return rnode;
    }

    // 获取第index位置的节点的值
    public T get(int index) {
        return getNode(index).value;
    }

    // 获取第1个节点的值
    public T getFirst() {
        return getNode(0).value;
    }

    // 获取最后一个节点的值
    public T getLast() {
        return getNode(mCount - 1).value;
    }

    // 将节点插入到第index位置之前
    public void insert(int index, T t) {
        if (index == 0) {
            DNode<T> node = new DNode<T>(t, mHead, mHead.next);
            mHead.next.prev = node;
            mHead.next = node;
            mCount++;
            return;
        }

        DNode<T> inode = getNode(index);
        DNode<T> tnode = new DNode<T>(t, inode.prev, inode);
        inode.prev.next = tnode;
        inode.next = tnode;
        mCount++;
        return;
    }

    // 将节点插入第一个节点处。
    public void insertFirst(T t) {
        insert(0, t);
    }

    // 将节点追加到链表的末尾
    public void appendLast(T t) {
        DNode<T> node = new DNode<T>(t, mHead.prev, mHead);
        mHead.prev.next = node;
        mHead.prev = node;
        mCount++;
    }

    // 删除index位置的节点
    public void del(int index) {
        DNode<T> inode = getNode(index);
        inode.prev.next = inode.next;
        inode.next.prev = inode.prev;
        inode = null;
        mCount--;
    }

    // 删除第一个节点
    public void deleteFirst() {
        del(0);
    }

    // 删除最后一个节点
    public void deleteLast() {
        del(mCount - 1);
    }

    public static void main(String[] args) {
        doubleLinkedTest();
    }

    /**
     * 双向链表测试方法
     */
    private static void doubleLinkedTest() {
        String[] testArr = {"ten", "twenty", "thirty", "forty"};
        System.out.println("\n----string_test----");
        // 创建双向链表
        ArryToDoubleLinked<String> ArryToDoubleLinked = new ArryToDoubleLinked<String>();
        ArryToDoubleLinked.insert(0, testArr[1]);   //  将testArr中第2个元素插入到第一个位置
        ArryToDoubleLinked.appendLast(testArr[0]);        //  将testArr中第1个元素追加到链表末尾
        ArryToDoubleLinked.insertFirst(testArr[2]);       //  将testArr中第3个元素插入到第一个位置
        // 双向链表的节点个数
        System.out.printf("size()=%d\n", ArryToDoubleLinked.size());
        // 循环遍历打印出双向链表全部的节点
        for (int i = 0; i < ArryToDoubleLinked.size(); i++)
            System.out.println("dlink(" + i + ")=" + ArryToDoubleLinked.get(i));
    }
}

 

相关标签: 双向链表