双向链表

package com.csmzxy.Link.T20121030;

class Link<T> {

 // 双向链表,有两个指针,一个向前,一个向后
 public T iData;

 public Link<T> previous = null;

 public Link<T> next = null;

 public Link(T iData) {
  this.iData = iData;
 }

 public void print() {
  System.out.print(iData + "\t");
 }
}

class LinkBothway {

 // 分别指向链表的表头和表尾
 private Link<String> first = null;

 private Link<String> last = null;
 
 /** 链表是否为NULL */
 public boolean isEmpty() {
  return first == null;
 }

 /** 在表头插入数据 */
 public void insertFirst(String key) {
  Link<String> newLink = new Link<String>(key);
  // 如果开始链表为空,则插入第一个数据后,last也指向第一个数据
  if (this.isEmpty()){
   last = newLink;
  }else {// 表不为空的情况
   first.previous = newLink;
   newLink.next = first;
  }
  // 无论怎样,插入后都的让first重新指向第一个节点 
  first = newLink;
 }
 /** 在尾端插入数据 */
 public void insertLast(String key) {
  Link<String> newLink = new Link<String>(key);
  // 如果开始链表为空,则插入第一个数据后,first也指向最后一个数据
  if (this.isEmpty())
   first = newLink;
  else {
   last.next = newLink;
   newLink.previous = last;
  }
  // 无论怎样,插入后都的让last重新指向最后一个数据
  last = newLink;
 }

 /**
  * 在指定的节点后插入数据
  *
  * @param key
  *            指定的节点的值
  * @param iData
  *            要插入的数据
  * @return 是否插入成功
  */
 public boolean insertAfter(String key, String iData) {
  Link<String> newLink = new Link<String>(iData);
  Link<String> current = first;
  // 从first开始遍历,看能否找到以key为关键字的节点
  while (!current.iData .equals(key) ) {
   current = current.next;
   // 若能找到就跳出循环,否则返回false,插入失败
   if (current == null)return false;
  }
  // 如果插入点在last的位置
  if (current == last) {
   last = newLink;
  } else {// 非last位置,交换各个next和previous的指针
   newLink.next = current.next;
   current.next.previous = newLink;
  }
  current.next = newLink;
  newLink.previous = current;
  return true;
 }

 /**删除表头的节点*/
 public Link<String> deleteFirst() {
  Link<String> temp = first;
  // 如果表中只有一个元素,删除后则为空表,所以last=null
  if (first.next == null)
   last = null;
  else
   // 否则,让第二个元素的previous=null
   first.next.previous = null;
  // 删除头指针,则first指向原来的second
  first = first.next;

  return temp;
 }
 /**删除表尾的节点*/
 public Link<String> deleteLast() {// 同上
  Link<String> temp = last;
  if (last.previous == null)
   first = null;
  else
   last.previous.next = null;
  last = last.previous;
  return temp;
 }
 /**删除指定的节点*/
 public Link<String> deleteKey(String key) {
  Link<String> current = first;
  // 遍历整个链表查找对应的key,如果查到跳出循环,否则...
  while (!key.equals(current.iData)) {
   current = current.next;
   // ...否则遍历到表尾,说明不存在此key,返回null,删除失败
   if (current == null)
    return null;
  }

  if (current == first)first = first.next;
  else current.previous.next = current.next;
  
  if (current == last)last = last.previous;
  else current.next.previous = current.previous;
  return current;
 }
 /**向前打印节点*/
 public void printForward() {
  Link<String> current = first;

  while (current != null) {
   current.print();
   current = current.next;
  }
  System.out.println();
 }
 /**向后打印节点*/
 public void printBackward() {
  Link<String> current = last;

  while (current != null) {
   current.print();
   current = current.previous;
  }
  System.out.println();
 }

 public static void main(String[] args) { // make a new list
  LinkBothway theList = new LinkBothway();

  theList.insertFirst("3"); // insert at front
  theList.insertFirst("2");
  theList.insertFirst("1");

  theList.insertLast("4"); // insert at rear
  theList.insertLast("5");
  theList.insertLast("6");

  theList.printForward(); // print list forward
  theList.printBackward(); // print list backward

  theList.deleteFirst(); // delete first item
  theList.printForward(); // print list forward
  theList.deleteLast(); // delete last item
  theList.printForward(); // print list forward
  theList.deleteKey("5"); // delete item with key 5
  theList.printForward(); // print list forward
  System.out.println("插入");
  theList.insertAfter("4", "6"); // insert 4 after 5
  theList.insertAfter("4", "5"); // insert 4 after 5
  theList.printForward(); // print list forward
 }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值