.线性表链式存储结构:将采用一组地址的任意的存储单元存放线性表中的数据元素。
链表又可分为:

  • 单链表:每个节点只保留一个引用,该引用指向当前节点的下一个节点,没有引用指向头结点,尾节点的next引用为null。

  • 循环链表:一种首尾相连的链表。

  • 双向链表:每个节点有两个引用,一个指向当前节点的上一个节点,另外一个指向当前节点的下一个节点。

下面给出线性表双向链表的实现:java中LinkedList是线性表的链式实现,是一个双向链表。

import java.util.NoSuchElementException;

//线性表双向链表存储结构
public class DuLinkList<T> {

//定义一个内部类Node,Node实例代表链表的节点
    private class Node{
        //保存节点的数据
        private T data;
        //指向上一个节点的引用
        private Node prev;
        //指向下一个节点的引用
        private Node next;
        //无参数的构造器
        public Node(){
            
        }
        //初始化全部属性的构造器
        public Node(T data, Node prev, Node next){
            this.data = data;
            this.prev = prev;
            this.next = next;
        }        
    }
    //保存该链表的头结点
    private Node header;
    //保存该链表的尾节点
    private Node tail;
    //保存该链表中已包含的节点数
    private int size;
    //创建空链表
    public DuLinkList(){
        //空链表,header与tail都是null
        header = null;
        tail = null;
    }
    //以指定数据元素来创建链表,该链表只有一个元素
    public DuLinkList(T element){
        header = new Node(element, null, null);
        tail = header;
        size++;
    }
    //判断链式线性表是否为空链表
    public boolean empty(){
        return size == 0;
    }
    //清空线性表
    public void clear(){
        for(Node current = header; current != null;){
            Node next = header.next;
            current.data = null;
            current.prev = null;
            current.next = null;
            current = next;
        }
        header = null;
        tail = null;
        size = 0;
    }
    //获取链式线性表中索引为index处的元素
    public T get(int index){
        return getNodeByIndex(index).data;
    }
    //根据索引index获取指定位置的节点
    private Node getNodeByIndex(int index){
        if(index < 0 || index > size -1){
            throw new IndexOutOfBoundsException("线性表索引越界");
        }
        if(index < (size >> 1)){
            //从header节点开始遍历
            Node current = header;
            for(int i=0; i < index; i++){
                current = current.next;
            }
            return current;
        }else{
            Node current = tail;
            for(int i = size - 1; i > index; i--){
                current = current.prev;
            }
            return current;
        }
    }
    //查找链式线性表中指定元素的索引
    public int locate(T element){
        Node current = header;
        for(int i=0;i<size && current != null;i++, current = current.next){
            if(current.data.equals(element)){
                return i;
            }
        }
        return -1;
    }
    //返回链表的长度
    public int length(){
        return size;
    }
    //向线性链表的表头插入一个元素
    public void addFirst(T element){
        linkFirst(element);
    }
    //在线性链表表头插入一个元素
    public void linkFirst(T element){
        Node f = header;
        Node newNode = new Node(element,null,f);
        header = newNode;
        if(f == null){
            tail = newNode;
        }else{
            f.prev = newNode;
        }
        size++;
    }
    //向线性链表的表尾插入一个元素
    public void addTail(T element){
        linkTail(element);
    }
    //在线性链表的表尾插入一个元素
    public void linkTail(T element){
        Node t = tail;
        Node newNode = new Node(element, t, null);
        tail = newNode;
        if(t == null){
            header = newNode;
        }else{
            t.next = newNode;
        }
        size++;
    }
    //在线性表中某个元素前面插入一个节点
    public void linkBefore(T element, Node node){
        Node pre = node.prev;
        Node newNode = new Node(element, pre, node);
        node.prev = newNode;
        if(pre == null){
            header = newNode;
        }else{
            pre.next = newNode;
        }
        size++;
    }
    //向线性链表中的指定位置插入一个元素
    public void insert(T element, int index){
        if(index < 0 || index > size){
            throw new IndexOutOfBoundsException("线性表索引越界");
        }
        if(index == size){
            addTail(element);
        }else{
            linkBefore(element,getNodeByIndex(index));
        }
    }
    //移走线性链表的头结点
    public void removeFirst(){
        Node first = header;
        if(first == null)
            throw new NoSuchElementException("此节点不存在");
        unlinkFirst(first);
    }
    //删除头结点
    public void unlinkFirst(Node node){
        Node next = node.next;    
        node.data = null;
        node.next = null;
        header = next;
        if(next == null){
            tail = null;
        }else{
            next.prev = null;
        }
        size--;
    }
    //移走线性链表的尾节点
    public void removeTail(){
        Node last = tail;
        if(last == null)
            throw new NoSuchElementException("此节点不存在");
        unlinkLast(last);
    }
    //删除尾节点
    public void unlinkLast(Node node){
        Node pre = node.prev;
        node.data = null;
        node.prev = null;
        tail = pre;
        if(pre == null){
            header = null;
        }else{
            pre.next = null;
        }
        size--;
    }
    //移走线性表中的任意一个节点
    public void remove(int index){
        if(index < 0 || index >size - 1){
            throw new IndexOutOfBoundsException("线性表越界");
        }
        unlink(getNodeByIndex(index));
    }
    //删除线性表中任意一个元素
    public void unlink(Node node){
        Node pre = node.prev;
        Node next = node.next;
        node.data = null;
        if(pre == null){
            header = next;
        }else{
            pre.next = next;
            node.prev = null;
        }
        if(next == null){
            tail = pre;
        }else{
            next.prev = pre;
            node.next = null;
        }
        size--;
    }
}

线性链表的双向链表——java实现的更多相关文章

  1. 【Java】 大话数据结构(5) 线性表之双向链表

    本文根据<大话数据结构>一书,实现了Java版的双向链表. 在每个数据结点中都有两个指针,分别指向直接后继和直接前驱,这样的链表称为双向链表. 双向链表的结构如图所示: 查找元素可以根据元 ...

  2. javascript实现数据结构:线性表--线性链表(链式存储结构)

    上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...

  3. 【二叉树->链表】二叉树结构转双向线性链表结构(先序遍历)

    二叉树存储结构属于非线性链表结构,转化成线性链表结构,能简化操作和理解.然而由非线性转线性需要对整个树遍历一次,不同的遍历方式转化结果页不一样.下面以先序为例. 方法一: 递归法.递归遍历二叉树,因为 ...

  4. c/c++ 线性表之双向链表

    c/c++ 线性表之双向链表 线性表之双向链表 不是存放在连续的内存空间,链表中的每个节点的next都指向下一个节点,每个节点的before都指向前一个节点,最后一个节点的下一个节点是NULL. 真实 ...

  5. [C++]线性链表之顺序表<二>

    /*   @content 线性链表之顺序表   @date 2017-3-21 1:06   @author Johnny Zen  */ /* 线性表     顺序表     链式表[带头指针/不 ...

  6. 【 C# 】(一) ------------- 泛型带头节点的单链表,双向链表实现

    在编程领域,数据结构与算法向来都是提升编程能力的重点.而一般常见的数据结构是链表,栈,队列,树等.事实上C#也已经封装好了这些数据结构,在头文件 System.Collections.Generic ...

  7. 线性表结构的Java实现

    一.线性表的抽象数据类型表述 线性表的结构简单,长度允许动态增长或搜索:可以对线性表中的任何数据元素进行访问和查找:允许进行数据的插入和删除操作:求线性表中的指定数据的前驱和后继:合并线性表以及拆分线 ...

  8. [数据结构 - 第3章] 线性表之双向链表(C语言实现)

    一.什么是双向链表? 双向链表(double linked list)是在单链表的每个结点中,再设置一个指向其前驱结点的指针域.所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前 ...

  9. 数据结构算法C语言实现(五)---2.3重新定义线性链表及其基本操作

    一.简述 ...由于链表在空间的合理利用上和插入.删除时不需要移动等的优点,因此在很多场合下,它是线性表的首选存储结构.然而,它也存在着实现某些基本操作,如求线性表的长度时不如顺序存储结构的缺点:另一 ...

随机推荐

  1. Linux下配置SSL (转)

    没有安装apache的情况: 首先安装SSL,再编译安装Apache,再配置证书即可 1.下载apache和openssl 网址:http://www.apache.org http://www.op ...

  2. xcode升级或者重新安装后不能编译的解决方法

    昨天由于xcode有一些问题,因此进行了重新安装,结果安装好后进行编译,没有进行任何改动的代码出现了两个fatal error 查看错误信息为什么的header has allready build, ...

  3. Android(java)学习笔记200:Android中View动画之 XML实现 和 代码实现

    1.Animation 动画类型 Android的animation由四种类型组成: XML中: alph 渐变透明度动画效果 scale 渐变尺寸伸缩动画效果 translate 画面转换位置移动动 ...

  4. GitHub Desktop安装异常解决

    为了更好的共同学习,共同进步,哥们推荐我使用GitHub记录自己每天的学习记录,当下很火的提供一个分布式的版本控制系统(Git)服务的网站,GitHub提供GitHub Desktop桌面程序方便协同 ...

  5. 在Weex中定制自定义组件

    1.配置自定义组件 public class MyViewComponent extends WXComponent{ public MyViewComponent(WXSDKInstance ins ...

  6. ASP.NET和支付宝合作开发第三方接口的注意事项

    最近公司和支付宝合作开发第三方接口的项目,这里把过程中需要注意的地方说明一下: 前提:一般来说单个银行不接收个人或私企开通支付接口.因此,和第三方支付公司合作,签订合约开放接口就是通行的做法. 流程: ...

  7. Singleton设计模式的一种见解

    单实例Singleton设计模式可能是被讨论和使用的最广泛的一个设计模式了,这可能也是面试中问得最多的一个设计模式了.这个设计模式主要目的是想在整个系统中只能出现一个类的实例.这样做当然是有必然的,比 ...

  8. ORACLE 数据库简单测试

    ORACLE 数据库简单测试 操作系统:Windows 7 – ORACLE:oracle database 10.2.0.4 一.目的 测试 启动监听程序.数据库  非同一个用户的情况,用户是否可以 ...

  9. iOS RC4加解密算法

    -(NSString *)encrypt:(NSString *)string withKey:(NSString *)key{ self.sBox = [[self frameSBox:key] m ...

  10. 关于ASIHTTPRequest连续请求,并发连续,间隔时间很小崩溃问题

    在不停的刷新ASIHttpRequest的网络请求时,总是在刷新几次之后,整个app崩溃掉.我的app使用的ARC模式,以为可以自动释放到request的请求.经过摸索,还是需要在dealloc函数加 ...