双向链表

来源:互联网 发布:火炮兰捏脸数据 编辑:程序博客网 时间:2024/05/01 21:41

与单链表上的插入和删除操作不同的是,在双链表中插入和删除必须同时修改两个方向上的指针。

 

package com.data.tree;

//双向链表 作者廖敏
public class LinkList<E> {
 // 定义单链表头用于标示第一个元素
 private transient ELinkList<E> head = new ELinkList<E>(null, null, null);
 // 定义单链表长度
 public transient int size = 0;

 // 添加第一个元素
 public void addFirst(E ele) {
  // 实例化链表元素
  ELinkList<E> temp = new ELinkList<E>(ele, null, null);
  // 如果没有第一个元素 添加第一个元素为temp
  if (head.next == null) {
   head.next = temp;
   temp.previous = head;
   // 存在第一个元素 当前元素的指向以前的一个元素 同时head指向当前元素
  } else {
   head.next.previous = temp;
   temp.next = head.next;
   temp.previous = head;
   head.next = temp;
  }
  size++;
 }

 // 添加第一个元素
 public void addLast(E ele) {
  // 实例化链表元素
  ELinkList<E> temp = new ELinkList<E>(ele, null, null);
  // 获取最后一个元素 并且最后一个元素指向当前元素
  ELinkList<E> e = getLastLink(null);
  // 若果最后一个元素不存在 就是没哟一个元素
  if (e == null)
   addFirst(ele);
  else {
   e.next = temp;
   temp.previous = e;
   size++;
  }
 }

 // 添加元素也是往第一个位置添加元素
 public void add(E ele) {
  addLast(ele);
 }

 // 删除第一个元素 判断第一个元素是否存在 如果存在 head指向第一个元素的下一个元素
 public void removeFirst() throws Exception {
  if (head.next != null) {
   head.next = head.next.next;
   size--;
  } else {
   throw new Exception("没有第一个元素");
  }
 }

 // 删除某个元素 因为没有指针指向第一个元素 所以添加参数 前参 和当前参数
 public boolean remove(E e, ELinkList<E> current) {
  // 定义临时参数
  ELinkList<E> currentlnk = null;
  // 如果当前参数为null 当前参数就是 第一个元素 也就是head.next
  // 前一个参数就是head
  if (current == null) {
   currentlnk = head.next;
   // 如果有值则 使用当前值
  } else {
   currentlnk = current;
  }
  if (currentlnk.data.equals(e)) {
   currentlnk.previous.next = currentlnk.next;
   if (currentlnk.next != null)
    currentlnk.next.previous = currentlnk.previous;
   size--;
   return true;
  } else {
   if (currentlnk.next == null)
    return false;
   return remove(e, currentlnk.next);
  }
 }

 // 重第一个元素开始遍历找到并删除该元素
 public boolean remove(E e) {
  return remove(e, null);
 }

 // 是否为空
 public boolean isEmpty() {
  if (head.next != null)
   return false;
  return true;
 }

 // 获得首个元素
 public E getFirst() {
  if (head.next == null)
   return null;
  return head.next.data;
 }

 // 获取指定索引的值 一直next .next 就会根据次数去next 去的值
 public E get(int index) throws Exception {
  if (index + 1 > size) {
   throw new IndexOutOfBoundsException("索引越界");
  }
  ELinkList<E> tmplnk = head;
  for (int i = 0; i <= index; i++) {
   tmplnk = tmplnk.next;
  }
  return tmplnk.data;
 }

 // 为了实现递归查询带的参数
 public E getLast(ELinkList<E> link) {
  ELinkList<E> next = null;
  if (link == null)
   next = head.next;
  else
   next = link;
  if (next.next == null)
   return next.data;
  else
   return getLast(next.next);
 }

 private ELinkList<E> getLastLink(ELinkList<E> link) {
  ELinkList<E> next = null;
  if (link == null)
   next = head.next;
  else
   next = link;
  if (next == null)
   return null;
  if (next.next == null)
   return next;
  else
   return getLastLink(next.next);
 }

 // 获得最后一个元素 
 public E getLast() {
  return getLast(null);
 }

 private class ELinkList<E> {
  public E data;
  public ELinkList<E> next;
  public ELinkList<E> previous;

  public ELinkList(E data, ELinkList<E> next, ELinkList<E> previous) {
   this.data = data;
   this.next = next;
   this.previous = previous;
  }

  public ELinkList(E data) {
   this(data, null, null);
  }
 }

}