双链表
双链表其实和单链表区别不大,与单链表相比,双链表的每个节点是由 一个数据 两个指针组成的,两个指针分别指向前驱和后继。
双链表与单链表相比的一个好处就是,双链表中的任意一个节点都可以比较容易的访问它的前驱和后继
双链表的实现
首先先介绍一下双链表的增加和删除一个节点功能的实现
实现代码
/*
* 线性表的接口的定义
*/
public interface MyList {
/*
* 增加元素
*/
void add(Object element);
/*
* 删除元素
*/
void delete(Object element);
//删除指定索引的元素
void delete(int index);
/*
* 更新元素
* 修改指定索引的值为新的element
*/
void update(int index,Object NewElement);
/*
* 查询元素
*/
boolean contains(Object target);
//查找element元素的索引 如果没有返回-1
int indexOf(Object element);
//返回指定索引的元素
Object at(int index);
}
public class ListNode {
Object data;
ListNode next; //记录当前访问节点的后面一个节点
ListNode pre; //记录当前访问节点的前面一个节点
public ListNode(Object data){
this.data = data;
}
}
/*
* 双链表的实现
*/
public class doubleLinkedList implements MyList {
private ListNode first = new ListNode(null); //头节点 亚元 不存放元素
private ListNode last = new ListNode(null); //最后的节点 亚元 不存放元素
private int size;
public doubleLinkedList()
{
first.next = last;
last.pre = first;
}
//向链表中添加一个节点
@Override
public void add(Object element) {
ListNode newNode = new ListNode(element);
last.pre.next = newNode;
newNode.next = last;
newNode.pre = last.pre;
last.pre = newNode;
size++;
}
//删除节点
@Override
public void delete(Object element) {
ListNode p = first.next;
while(p!=last)
{
if(p.data.equals(element))
{
p.pre.next = p.next;
p.next.pre = p.pre;
p.next = null;
p.pre = null;
size--;
break;
}
p = p.next;
}
}
//通过给定的索引值去删除节点
//需要考虑的一个问题就是 一直删的话 会不会出现越界问题
@Override
public void delete(int index) {
//先判断索引值 是否在范围内 如果不在话 直接return
if(index<0||index>=size)
{
return;
}
ListNode p = first.next;
int i = 0; //和每个结点相对应
while(p != last)
{
if(i == index)
{
p.pre.next = p.next;
p.next.pre = p.pre;
p.next = null;
p.pre = null;
size--;
break;
}
i++;
p = p.next;
}
}
@Override
public void update(int index, Object NewElement) {
//先判断索引值 是否在范围内 如果不在话 直接return
if(index<0||index>=size)
{
return;
}
ListNode p = first.next;
int i = 0; //和每个结点相对应
while(p != last)
{
if(i == index)
{
p.data = NewElement;
break;
}
i++;
p = p.next;
}
}
@Override
public boolean contains(Object target) {
ListNode p = first.next;
while(p != last)
{
if(p.data.equals(target))
{
return true;
}
p = p.next;
}
return false;
}
@Override
public int indexOf(Object element) {
ListNode p = first.next;
int i = 0;
while(p!=last)
{
if(p.data.equals(element))
{
return i;
}
i++;
p = p.next;
}
return -1;
}
@Override
public Object at(int index) {
if(index<0||index>=size)
{
return null;
}
int i = 0;
ListNode p = first.next;
while(p!=last)
{
if(i == index)
{
return p.data;
}
i++;
p = p.next;
}
return null;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
//遍历 首先需要将头节点先复制一下 不能直接将头节点拿过来使用
ListNode p = first.next;
while(p!=last)
{
sb.append(p.data);
if(p.next!=last)
{
sb.append(",");
}
p = p.next;
}
sb.append("]");
return sb.toString();
}
}
测试
public class Test {
public static void main(String[] args) {
doubleLinkedList d = new doubleLinkedList();
d.add("a");
d.add("b");
d.add("c");
d.add("d");
d.add("e");
System.out.println(d);
d.delete("a");
System.out.println(d);
d.delete(1);
System.out.println(d);
}
}
结果:
[a,b,c,d,e]
[b,c,d,e]
[b,d,e]