前篇->有序链表
在传统链表中我们寻找下一个结点是否方便,但是如果要追溯前面的结点是比较困难的。
双向链表提供了反向遍历的能力。其秘密在于每个结点有两个指向其他结点的引用,一个指向前继结点,一个指向后继结点。下图显示了双向链表:
代码实现双向链表
Link类(结点)的定义
public class Link {
public int data;
public Link previous;
public Link next;
public Link(int data){
this.data = data;
}
public void displayLink(){
System.out.print(this.data + " ");
}
}
结点插入
结点的插入有三种情况:在首部插入,在尾部插入和任意位置插入。现在分别实现这三种情况的代码。
首部插入
这是链表不为空时的插入顺序,当链表为空时插入结点需要注意last的更新。
public class DoubleList {
private Link first;
private Link last;
//判断链表是否为空
public boolean isEmpty(){
return first==null;
}
/**
* 从首部插入结点
* @param data
*/
public void insertFirst(int data){
Link newNode = new Link(data);
if(isEmpty()){//当list为空时需要更新last
last = newNode;
}else{
first.previous = newNode;
}
newNode.next = first;
first = newNode;
}
}
尾部插入
注意链表为空时的插入。
/**
* 从尾部插入
*/
public void insertLast(int data){
Link newNode = new Link(data);
if(isEmpty()){
first = newNode;
}else{
last.next = newNode;
newNode.previous = last;
}
last = newNode;
}
任意位置插入
/**
* 将指定数据插入到指定结点后
* @param key {指定结点的值}
* @param data {待插入数据值}
* @return boolean {成功插入返回true,否则返回false}
*/
public boolean insertAfter(int key,int data){
Link newNode = new Link(data);
Link current = first;
while(current!=null&¤t.data!=key){
current = current.next;
}
if(current==null)
return false;
if(current==last){
last = newNode;
}else{
newNode.next = current.next;
current.next.previous = newNode;
}
newNode.previous = current;
current.next = newNode;
return true;
}
结点删除
结点的插入有三种情况:在首部删除,在尾部删除和任意位置删除。现在分别实现这三种情况的代码。
首部删除
/**
* 首部删除
*/
public void deleteFirst(){
Link temp = first;
if(first.next == null)
last = null;//只有一个结点,删除后需要更新last
else
first.next.previous = null;
first = first.next;
return temp;
}
尾部删除
/**
* 尾部删除
*/
public void deleteLast(){
Link temp = last;
if(first.next == null)
first = null;
else
last.previous.next = null;
last = last.previous;
return temp;
}
任意位置删除
/**
* 任意位置删除
*/
public Link deleteKey(int key){
Link current=first;
while(current!=null&¤t.data!=key){
current = current.next;
}
if(current==null)
return null;
if(first==current)
first = current.next;
else
current.previous.next = current.next;
if(current==last)
last = current.previous;
else
current.next.previous = current.previous;
return current;
}
链表遍历
双向链表的遍历有两种情况:从前向后和从后向前。现在实现这两种情况的代码。
public void displayForward(){
System.out.println("first-->last:");
Link current = first;
while(current!=null){
current.displayLink();
current = current.next;
}
System.out.println();
}
public void displayBackward(){
System.out.println("last-->first:");
Link current = last;
while(current!=null){
current.displayLink();
current = current.previous;
}
System.out.println();
}
链表测试
public class TestMain {
public static void main(String[] args) {
DoubleList list = new DoubleList();
list.insertFirst(1);
list.insertFirst(2);
list.insertFirst(3);
list.insertLast(4);
list.insertLast(5);
list.insertAfter(3, 6);
list.displayForward();
list.displayBackward();
//删除
System.out.println("delete first:");
list.deleteFirst();
list.displayForward();
System.out.println("delete last:");
list.deleteLast();
list.displayBackward();
System.out.println("delete key==4:");
list.deleteKey(4);
list.displayBackward();
}
}