java 线性表和链表_线性表--双链表实现方式 (JAVA)

欢迎讨论,转载请注明出处哦

前面一篇文章说明了线性表主要有三种结构:顺序表、单链表、双链表。

其实按照其实现的特点是两种实现方式:1、采用数组式的静态存储空间,即线性表;2、采用链

式的动态 存储空间,即是链表。

上一章实现了顺序表,这篇文章用于实现双链表。由于双链表具有的方法比顺序表多。

因此重新定义一个线性表接口: package com.kiritor.linklist; /** * 线性表接口 * @author Kiritor * */ public interface LinearTable{ //判空 public boolean isEmpty(); //获取长度 public int getLength(); //返回某个位置的元素 public T getData(int index); //设置index位置的元素,并返回先前的元素 public T setData(int index,T element); //插入一个元素,位置没有限定(插入链表尾部) public boolean addData(T element); //在指定的位置插入一个元素 public boolean addData(int index,T element); //删除某个位置的元素,并返回该元素 public T removeData(int index); //清空线性表 public boolean clearData(); //删除尾部 public boolean removeTail(); }                  接下来就是实现了

package com.kiritor.linklist; /**  * java版双向链表的实现  *  * @author Kiritor  */ public class DBLinkList implements LinearTable {     // 指向链表的头结点     private Node head;     // 指向链表的尾结点     private Node tail;     private int size = 0;// 链表的元素个数     public DBLinkList() {         this.head = new Node();         this.tail = null;     }     public DBLinkList(T data) {         this.head = new Node(null, data, null);         this.tail = this.head;         this.size++;     }     @Override     public boolean isEmpty() {         // TODO Auto-generated method stub         return this.size == 0;     }     // 获得链表的长度     public int getLength() {         return this.size;     }     // 获取指定位置结点,下表从0开始     public Node getNode(int index) {         if (index < 0 || index > this.size - 1)             throw new IndexOutOfBoundsException("访问位置非法越界!");         // 根据index所出的位置决定是从前遍历还是从后遍历         if (index <= this.size / 2) {// 位置在前半部分,则从头开始搜索             Node curent = this.head;             for (int i = 0; i <= this.size / 2 && curent != null; i++, curent = curent.next)                 if (i == index)                     return curent;         } else {// 位置在后半部分,则从后开始往前搜索             Node curent = this.tail;             for (int i = this.size - 1; i > this.size / 2 && curent != null; i--, curent = curent.pre)                 if (i == index)                     return curent;         }         return null;     }     // 获取指定位置的结点元素     public T getData(int index) {         return this.getNode(index).data;     }     @Override     public T setData(int index, T element) {         return null;     }     // 在链表的头部插入元素,不指定位置默认在头部插入     @Override     public boolean addData(T element) {         // 前驱引用为null,后继引用为头结点         Node node = new Node(null, element, this.head);         this.head.pre = node;// 改变前驱引用         // 修改链表的头结点         this.head = node;         if (tail == null)             tail = this.head;         this.size++;         // System.out.println(head.data+""+this.size);         return true;     }     // 尾部插入     public boolean addTail(T data) {         if (this.head == null) {             this.head = new Node(null, data, null);             this.tail = this.head;         } else {             Node newnode = new Node(this.tail, data, null);             this.tail.next = newnode;             this.tail = newnode;         }         this.size++;         // System.out.println(tail.data+""+this.size);         return true;     }     //下表从0开始     @Override     public boolean addData(int index, T element) {         if (index < 0 || index > this.size)             throw new IndexOutOfBoundsException("不能在该位置插入元素,索引越界");         if (this.head == null)             this.addTail(element);// 尾部插入         else {             if (index == 0)                 this.addData(element);// 头部插入             else {                 Node prev = this.getNode(index - 1);// 找到index-1处的节点                 Node next = prev.next;                 Node newnode = new Node(prev, element, next);// 分配节点                 prev.next = newnode;                 next.pre = newnode;                 this.size++;             }         }         return true;     }     public String toString() {         if (this.isEmpty())             return "[]";         else {             StringBuffer st = new StringBuffer("[");             for (Node curent = this.head; curent != null; curent = curent.next)                 st.append(curent.data.toString() + " ,");             st.append("]");             return st.toString();         }     }     // 反向遍历链表     public String reversetoString() {         if (this.isEmpty())             return "[]";         else {             StringBuffer st = new StringBuffer("[");             for (Node curent = this.tail; curent != null; curent = curent.pre)                 st.append(curent.data.toString() + " ,");             st.append("]");             return st.toString();         }     }     /**删除指定位置的结点,下表从0开始*/     @Override     public T removeData(int index) {         if (index < 0 || index > this.size - 1)             throw new IndexOutOfBoundsException("不能删除该位置的元素,索引越界");         Node del = null;         if (index == 0) {// 删除的为头节点             del = this.head;             this.head = this.head.next;             this.head.pre = null;             size--;         }         else if(index==size-1)         {             Node prev = this.getNode(index - 1);//找到删除位置的前驱             del = prev.next;//找到要删除的结点             prev.next = del.next;             if (del.next != null)                 del.next.pre = prev;             del.pre = null;             del.next = null;                          size--;             this.tail.next = null;             this.tail.pre=prev;             this.tail = prev;         }         else {             Node prev = this.getNode(index - 1);//找到删除位置的前驱             del = prev.next;//找到要删除的结点             prev.next = del.next;             if (del.next != null)                 del.next.pre = prev;             del.pre = null;             del.next = null;                          size--;                      }         return null;     }     @Override     public boolean removeTail() {         removeData(this.size-1 );         return false;     }     public int getSize() {         return size;     }     public void setSize(int size) {         this.size = size;     }     @Override     public boolean clearData() {         this.head = null;         this.tail = null;         this.size = 0;         return true;     }     /** 链表的节点类型 */     class Node {         public T data;         public Node pre;// 便于访问的需要,设置为public         public Node next;         public Node() {         };         public Node(Node pre, T data, Node next) {             this.data = data;             this.pre = pre;             this.next = next;         }     }      }             简单的看看输出结果:

2f8f0c4bb653e17a93fc0fa800f28ce8.png

对于其具体分析就一个removeData(int index)方法为例吧(index>=1&&index<=size-1)

0547b0356834d03960d21e02981023d3.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值