zoukankan      html  css  js  c++  java
  • 2019-03-19 java数据结构(三) 双向链表

     一、双向链表的示意图

    二、java代码实现:

    /**
     * 双向链表
     * 注:jdk有自带的双向链表,路径是:java.util.LinkedList
    * @author ljtao3 * @param <T> */ public class DoubleLink { //表头 public DNode mHead; //节点个数 public int mCount; private class DNode { public DNode prev; public DNode next; public Object data; public DNode(Object data,DNode prev,DNode next){ this.data=data; this.prev=prev; this.next=next; } } public DoubleLink(){ //创建表头,表头没有存储数据 mHead=new DNode(null,null,null); //这个很关键,一开始时让表头前后指向自己,后面的appendLast方法,当mCount=0时,才不会报错 mHead.next=mHead.prev=mHead; mCount=0; } public int size(){ return mCount; } public boolean isEmpty(){ return mCount==0; } //获取节点 private DNode getNode(int index) { if(index<0||index>=mCount) throw new IndexOutOfBoundsException("index:"+index+",size:"+mCount); DNode node=mHead; //进行判断,如果属于前半部分就正向查询,如果属于后半部分就反向查询 if(index<(mCount>>1)){ for (int i = 0; i <= index; i++) node=node.next; } else{ for (int i = mCount-1; i >= index; i--) node=node.prev; } return node; } //获取节点的值 public Object get(int index){ return getNode(index).data; } public Object getFirst(){ return mHead.next.data; } public Object getLast(){ return mHead.prev.data; } //将节点插入到第index位置 public void insert(int index, Object t){ if(index<0||(index>mCount && index!=0)) throw new IndexOutOfBoundsException("index:"+index+",size:"+mCount); if(index==mCount) { appendLast(t); return; } if(index==0 && isEmpty()){ DNode now0=new DNode(t,mHead,mHead); mHead.next=now0; mHead.prev=now0; mCount++; return; } DNode p=getNode(index).prev; DNode n=getNode(index); DNode now=new DNode(t,p,n); p.next=now; n.prev=now; mCount++; } public void remove(int index){ if(index<0||index>=mCount) throw new IndexOutOfBoundsException("index:"+index+",size:"+mCount); DNode p=getNode(index).prev; DNode n=getNode(index).next; p.next=n; n.prev=p; mCount--; } public void insertFirst(Object t){ insert(0,t); } // 将节点追加到链表的末尾 public void appendLast(Object t){ DNode now=new DNode(t,mHead.prev,mHead); //这里如果列表是空的话,需要另做操作 mHead.prev.next=now; mHead.prev=now; mCount++; } public void deleteFirst() throws Exception{ del(0); } public void del(int index){ DNode now=getNode(index); DNode p=now.prev; DNode n=now.next; p.next=n; n.prev=p; now=null; mCount--; } public void deleteLast(){ del(mCount-1); } public void display(){ DNode now=mHead; for (int i = 0; i < mCount; i++) { now=now.next; System.out.println(now.data.toString()); } } }

    三、测试代码

    public static void demo3() throws Exception{
            DoubleLink dl=new DoubleLink();
            dl.insertFirst("i:1");
            dl.insertFirst("i:2");
            dl.appendLast("i:4");
            dl.insert(3, "i:5");
            dl.display();
            System.out.println("---------");
            dl.deleteFirst();
            dl.remove(2);
            dl.remove(0);
            dl.display();
            
        }

    输出:

    四、过程总结。

    1、部分代码是参考jdk中的源代码来实现的。

    2、在创建双向链表的时候,一开始赋值要使表头的前后都指向表头。

    3、getNode() 方法 实现有点技巧,先判断位置在前半部分还是在后半部分,选择正向查询,或者反向查询。

  • 相关阅读:
    kafka控制测试发送接收消息
    Kafka 启动报错java.io.IOException: Can't resolve address.
    java问题 2019
    java各种面试问题
    java 架构师
    开源的13个Spring Boot 优秀学习项目!超53K星,一网打尽!
    Dubbo 18 问
    Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。
    XMind2TestCase 工具,提供了一个高效测试用例设计的解决方案(开源)
    windows下面安装Python和pip终极教程
  • 原文地址:https://www.cnblogs.com/mathlin/p/10648574.html
Copyright © 2011-2022 走看看