zoukankan      html  css  js  c++  java
  • 数据结构--双向循环链表

    参考双循环链表就是头尾相连,并且每一个结点都可以指向它的前驱和后继的链表。

    java代码实现

    双向链表类

    package sy180923;
    
    public class DoubleLink<T>
    {
        //表头
        private DNode<T> mHead;
        //节点个数
        private int mCount;
        
        public DoubleLink()
        {
            //链表表头 为空不存数据
            mHead=new DNode<T>(null,null,null);
            //表头的前驱后继都是自己
            mHead.prev=mHead.next=mHead;
            //没有节点,空的
            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;
            //比如 index=7,mCount=10
            //就是从10-7-1=2(下标从0)
            //就是找 10  9  的前面那个
            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;
        }
        public T getFirst()
        {
            return getNode(0).value;
        }
        public T getLast()
        {
            return getNode(mCount-1).value;
        }
        //前插
        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;
            }
            //比如我要插在第二个数的前面 index=2
            DNode<T>inode=getNode(index);
            //新来一个节点,在这个下标前面
            //这句话指的是这个新来的是inode的前驱是新来的前驱,inode是新来的后继
            DNode<T>tnode=new DNode<T>(t,inode.prev,inode);
            //inode的前一个的后继是这个新来的
            inode.prev.next=tnode;
            //inode.next=tnode;这不对
            //改正如下
            //inode的前一个是这个新来的
            inode.prev=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++;
        }
        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);
        }
    }

    节点类

    package sy180923;
    
    //双向链表“节点”
    public    class DNode<T>
        {
            public DNode prev;//前驱
            public DNode next;//后继
            public T value;//存储类型的值
            public DNode(T value,DNode prev, DNode next)
            {
                super();
                this.prev = prev;
                this.next = next;
                this.value = value;
            }
            
        }

    测试类

    package sy180923;
    
    public class DlinkTest
    {
        // 双向链表操作int数据
        private static void int_test() {
            int[] iarr = {10, 20, 30, 40};
    
            System.out.println("
    ----int_test----");
            // 创建双向链表
            DoubleLink<Integer> dlink = new DoubleLink<Integer>();
    
            dlink.insert(0, 20);    // 将 20 插入到第一个位置
            dlink.appendLast(10);    // 将 10 追加到链表末尾
            dlink.insertFirst(30);    // 将 30 插入到第一个位置
            dlink.insert(2,40);
            dlink.insert(3,70);
            dlink.insert(2,80);
            // 双向链表是否为空
            System.out.printf("isEmpty()=%b
    ", dlink.isEmpty());
            // 双向链表的大小
            System.out.printf("size()=%d
    ", dlink.size());
    
            // 打印出全部的节点
            for (int i=0; i<dlink.size(); i++)
                System.out.println("dlink("+i+")="+ dlink.get(i));
        }
        public static void main(String[] args) {
            int_test();        // 演示向双向链表操作“int数据”。
           
        }
    
    }

    主要代码分析

    结果

    参考:

    http://www.cnblogs.com/skywang12345/p/3561803.html

    https://www.cnblogs.com/kangjianwei101/p/5224236.html

  • 相关阅读:
    Git windows换行问题
    java之aop使用及自定义注解
    Shiro授权及注解式开发
    Git Gui、Ssh key的使用和ideaui配置使用Git解决冲突(下)
    Git和Github的介绍、简单操作、冲突(上)
    Shiro身份认证、盐加密
    Shiro简介、入门案例、web容器的集成
    SpringMVC入门
    Mybatis之关联关系(一对多、多对多)
    Mybatis整合(Redis、Ehcache)实现二级缓存
  • 原文地址:https://www.cnblogs.com/symkmk123/p/9693872.html
Copyright © 2011-2022 走看看