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() 方法 实现有点技巧,先判断位置在前半部分还是在后半部分,选择正向查询,或者反向查询。

  • 相关阅读:
    Kubernetes 集成研发笔记
    Rust 1.44.0 发布
    Rust 1.43.0 发布
    PAT 甲级 1108 Finding Average (20分)
    PAT 甲级 1107 Social Clusters (30分)(并查集)
    PAT 甲级 1106 Lowest Price in Supply Chain (25分) (bfs)
    PAT 甲级 1105 Spiral Matrix (25分)(螺旋矩阵,简单模拟)
    PAT 甲级 1104 Sum of Number Segments (20分)(有坑,int *int 可能会溢出)
    java 多线程 26 : 线程池
    OpenCV_Python —— (4)形态学操作
  • 原文地址:https://www.cnblogs.com/mathlin/p/10648574.html
Copyright © 2011-2022 走看看