双向链表和我们前面讲的单链表最大的区别就是多了一个前驱结点
我们第一步还是定义Sequence接口,它里面都是双向链表一些基本的操作,增删查改等
Sequence接口定义如下:
public interface Sequence { /** * 向线性表中添加元素 * @param date 要存储的元素 */ void add(Object date); /** * 线性表中删除元素 * @param index 要删除的元素下标 * @return 是否删除成功 */ boolean remove(int index); /** * 在线性表中查找指定下标的元素 * @param index 要查找的索引 * @return */ Object get(int index); /** * 判断线性表中是否有指定元素 * @param data 要查找的元素内容 * @return */ boolean contains(Object data); /** * 修改线性表中指定索引的内容 * @param index 要修改元素下标 * @param newData 修改后的内容 * @return */ Object set(int index,Object newData); /** * 返回当前线性表的长度 * @return */ int size(); /** * 清空线性表内容 */ void clear(); /** * 将线性表转为数组 * @return */ Object[] toArray();
下面是双向链表类中实现Sequence接口的方法实现:
首先我们先定义DoubleLinkListImpl类,
public class DoubleLinkedListImpl implements Sequence{ //表示头结点 private ListNode head; //表示尾结点 private ListNode tail; //链表长度 private int size; //内部类ListNode private class ListNode { private ListNode prev; private ListNode next; Object data; public ListNode(ListNode prev , Object data, ListNode next) { this.prev = prev; this.next = next; this.data = data; } public ListNode(Object data) { this.data = data; } } }
该类中具体实现方法我们一步一步写出来:
checkIndex方法:
//检查索引index是否合法 private void checkIndex(int index) { if(index < 0 || index >= size) { throw new IndexOutOfBoundsException("Illeagle Index"); } }
node方法:
//获取当前索引结点private ListNode node(int index) { ListNode tmp = head; for(int i = 0;i<index;i++) { tmp = tmp.next; } return tmp; }
add方法:
/** * 尾插法 */ public void add(Object date) { // TODO Auto-generated method stub ListNode node = new ListNode(tail,date,null); if(head == null) { head = node; }else { tail.next = node; } tail = node; size++; }
remove方法:
public boolean remove(int index) { // TODO Auto-generated method stub checkIndex(index); //要删除结点 ListNode now = node(index); ListNode prevNode = now.prev; ListNode nextNode = now.next; //要删除的是头结点 if(prevNode == null) { head = nextNode; }else { prevNode.next = now.next; now.prev = null; } //要删除的是尾结点 if(nextNode == null) { tail = now.prev; }else { nextNode.prev = now.prev; now.prev = null; } size--; return true; }
get方法:
public Object get(int index) { // TODO Auto-generated method stub checkIndex(index); return node(index).data; }
contains方法:
public boolean contains(Object data) { // TODO Auto-generated method stub ListNode tmp = head; while(tmp!=null) { if(tmp.data.equals(data)) { return true; } tmp = tmp.next; } return false; }
set方法:
public Object set(int index, Object newData) { // TODO Auto-generated method stub checkIndex(index); ListNode node = node(index); node.data = newData; return newData; }
clear方法:
@Override public void clear() { // TODO Auto-generated method stub for(ListNode tmp = head;tmp!=null;) { ListNode next = tmp.next; tmp.prev = tmp.next = null; tmp.data = null; tmp = next; size--; } }
size方法:
public int size() { // TODO Auto-generated method stub return size; }
toArray方法:
public Object[] toArray() { // TODO Auto-generated method stub Object[] object = new Object[size]; int i = 0; for(ListNode tmp = head;tmp!=null;tmp = tmp.next) { object[i++] = tmp.data; } return object; }
完整代码链接:https://github.com/dukaichao/DataStructure/tree/master/dkc_ds_0319
来源:https://www.cnblogs.com/du001011/p/10558384.html