Java学习笔记<十五>

Java学习笔记<十五>,第1张

package DataStructure_8;

//双向链表--实现双向链表

/**
*双线链表结构
 * 双向链表定义:
 * 双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向直接前驱和直接后继
 *
 */

/**
 *基于双向链表存取的数据
 * @param 
 */
//实现单向链表类的中定义的MyList接口
public class Text3 implements MyList {

    private Node head;      //头结点指针
    private Node tail;      //尾结点指针
    private int size;       //记录元素个数

    //创建节点类(内部类)
    class Node{

        E item;             //记录元素
        Node prev;       //记录链表中前一个节点对象地址
        Node next;       //记录链表中后一个节点对象地址

        public Node(E item, Node prev, Node next) {
            this.item = item;
            this.prev = prev;
            this.next = next;
        }

    }


    /**
     * 向双向链表中添加元素
     * @param element
     */
    @Override
    public void add(E element) {

        //头结点和尾结点的添加都使用LinkLast()方法
        this.LinkLast(element);

    }

    //为链表中添加头结点的方法
    private void addFirst(E element){

        //将原头结点指针赋给可移动指针
        Node uu=this.head;
        //创建一个新的头结点
        Node node = new Node<>(element,null,uu);
        //为新节点指定头指针
        this.head=node;
        //如果新节点为唯一节点,则新节点也是尾结点
        if (uu==null){
            this.tail=node;
        }else {
            //如果新节点不是唯一节点,将新节点地址赋给原头指针所对应的原头结点的prev
            uu.prev=node;
        }
        this.size++;

    }

    //为链表中添加尾结点的方法
    private void addLast(E element){

        //直接调用LinkLast()方法添加尾结点
        this.LinkLast(element);

    }

    //向双向链表中添加尾结点
    private void LinkLast(E element){

        //将尾结点赋给t
        Node t=this.tail;
        //创建新节点,新节点的前驱节点为尾结点t,后继几点为null
        Node node = new Node<>(element,t,null);      //前驱节点挂接
        //新创建的节点为尾结点
        this.tail=node;
        //如果如果之前的尾结点的前驱节点为空,则新节点就是第一个节点对象,将新节点定为头结点
        if (t==null){
            this.head=node;
            //如果之前尾结点的前驱节点不为空,说明有尾结点,将新节点的地址赋给尾结点的next,(尾结点可能和头结点为一个节点)
        }else{
            t.next=node;
        }
        size++;
    }


    /**
     * 根据索引获取元素
     * @param index
     * @return
     */
    @Override
    public E get(int index) {

        //对index做合法性校验
        this.checkIndex(index);
        //根据index查找节点对象
        Node node = this.getNode(index);
        //返回节点元素
        return node.item;
    }

    //校验index合法性
    private void checkIndex(int index){

        if (!(index >= 0 && index < this.size)){
            throw new IndexOutOfBoundsException("Index "+index+" size "+size);
        }
    }

    //根据index查询并返回元素
    private Node getNode(int index){

        //使用二分法查找
        if (index < (this.size>>1)){
            Node aa=this.head;
            for (int i = 0; i < index; i++) {
                aa=aa.next;
            }
            return aa;
        }else {
            Node aa = this.tail;
            for (int i = (this.size-1); i >= index; i--) {
                aa=aa.prev;
            }
            return aa;
        }
    }

    /**
     * 获取元素个数
     * @return
     */
    @Override
    public int size() {
        return this.size;
    }

    /**
     * 根据指定索引删除元素
     * @param index
     * @return
     */
    @Override
    public E remove(int index) {

        //对index进行合法性校验
        this.checkIndex(index);
        //根据位置获取节点对象
        Node node =this.getNode(index);
        //获取节点对象中的元素
        E item=node.item;
        //判断当前节点是否为头结点
        if (node.prev==null){
            this.head=node.next;
            node.next=null;
            node.item=null;
        }else {
            //当前节点删除后当前节点的前驱节点与后续节点的挂接
            //当前节点的前驱节点的next指向当前节点的next节点(也就是当前节点的后继节点)
            node.prev.next=node.next;
        }
        //判断当前节点是否为尾结点
        if (node.next==null){
            this.tail=node.prev;
        }else {
            //完成当前节点的后继节点的prev与当前节点的前驱节点挂接
            node.next.prev=node.prev;
        }
        //当前节点断掉直接前驱节点的链接
        node.prev=null;
        //当前节点断掉直接后继节点的链接
        node.next=null;
        //将当前节点内元素置空,加速垃圾回收效率
        node.item=null;
        //记录元素个数
        this.size--;
        //返回当前元素
        return node.item;
    }

    public static void main(String[] args) {

        System.out.println("==============测试双向链表类的功能====================");
        Text3 nn=new Text3<>();

        nn.add("a");
        nn.add("b");
        nn.add("c");
        nn.add("d");

        System.out.println(nn.size);

        System.out.println(nn.get(2));

        String kk= nn.remove(2);

        for (int i = 0; i  oo = new Text3<>();

        oo.addFirst("a");
        oo.addLast("A");
        oo.addFirst("B");

        for (int i = 0; i < oo.size; i++) {
            System.out.println(oo.get(i));
        }
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/759911.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-01
下一篇 2022-05-01

发表评论

登录后才能评论

评论列表(0条)

保存