- 今天就是五一了。有女朋友得都出去浪去了。然而像我这单身屌丝。只能在家撸代码。真是代码虐我千百遍,我对代码如初恋。一天就是10个小时的学习开始了。
- 今天我们学习双向链表用java实现。因为以前学习数据结构的没用功,以至于现在学了一早上也仅仅理解了一些。
- 什么是双向链表呢?
- 每一个结点除了保存对下一个结点的的引用,同时还保存对前一个结点的引用
- 从头部进行插入
- 要对链表进行判断
- 要对链表进行判断,如果为空的话就设置尾结点为新添加的结点,如果不为空,还需要设置头结点的前一个结点为新添加的结点。
- 从尾部插入
- 如果链表为空,直接设置头结点为新添加的结点。否则设置尾结点的后一个结点为添加的结点。同时设置添加的结点的前一个的引用
数据结构如下图:
废话不多说话了直接上代码
先创建一个结点类
/**
* 双向链表需要的节点
* @author Administrator
*
*/
public class Link {
public long data;
//指针域
public Link next;
//指针域
public Link provious;
public Link(long dd){
data = dd;
}
public void display(){
System.out.print(data+" ");
}
}
在创建双向链表的实现
public class DoublyLink {
//头节点
private Link first;
//尾节点
private Link last;
public DoublyLink(){
first = null;
last = null;
}
/**
* 从头节点开始添加
* @param d
*/
public void insertFirst(long d){
Link newlink = new Link(d);
if(isEmpty()){
last = newlink;//如果为空话。last = 新添加的节点
}else{
first.provious = newlink;//第一个的前一指针指向先节点
}
newlink.next =first;//新节点的next指向 原来的第一个
first =newlink;//第一个变成新的
}
public void insertLast(long d){
Link newlink = new Link(d);
if(isEmpty()){
first = newlink;
}else{
last.next=newlink;
newlink.provious=last;
}
last = newlink;
}
public Link deleteFirst(){
Link temp = first;
if(first.next == null){
last = null;
}else{
first.next.provious =null;
}
first = first.next;
return temp;
}
public Link deleteLast(){
Link temp = last;
if(last.provious ==null){
first = null;
}else{
//清楚前一个的引用
last.provious.next=null;
}
last =last.provious;
return temp;
}
public boolean insertAfter(long key,long data){
Link newLink = new Link(data);
Link current =first;
while(current.data !=key){
current= current.next;
if(current ==null){
return false;
}
}
if(current == last){
newLink.next=null;
last = newLink;
}else{
//设置newLink 的前后的指针
newLink.next =current.next;
current.next.provious =newLink;//设置要添加的节点的下一个的前一个的指针域
}
newLink.provious = current;
current.next= newLink;
return true;
}
public Link deletekey(long key){
Link current = first;
while(current.data != key){
current = current.next;
if(current == null){
return null;
}
}
//1,先处理next 的引用
if(current == first){
//删除第一个节点。
first =first.next;
}else{
//如果不是第一个就删除前一个节点的next 引用
current.provious.next = current.next;
}
// 在处理provious 的引用
if(current == last){//如果是最后一个的话,就删除最后一个
last =current.provious;
}else{
//[1][2][3] 当前的下一个的provious 指向要删除的这个节点的prov
current.next.provious = current.provious;
}
return current;
}
public void displayForward(){
System.out.print("first--->last:");
Link current = first;
while(current!=null){
current.display();
current = current.next;
}
System.out.println();
}
public void displayBackward(){
System.out.print("last--->first:");
Link current = last;
while(current!=null){
current.display();
current = current.provious;
}
System.out.println();
}
public boolean isEmpty(){
return first == null;
}
}
在创建测试类:
public static void main(String[] args) {
DoublyLink d = new DoublyLink();
d.insertFirst(20);
d.insertFirst(40);
d.insertFirst(60);
d.insertLast(11);
d.insertLast(33);
d.insertLast(55);
d.displayForward();
d.displayBackward();
d.deleteFirst();
d.deleteLast();
d.displayForward();
d.deletekey(11);
d.displayForward();
d.insertAfter(20, 25);
d.insertAfter(33, 77);
d.displayForward();
d.deletekey(40);
d.displayForward();
}
测试结果如下:
first--->last:60 40 20 11 33 55
last--->first:55 33 11 20 40 60
first--->last:40 20 11 33
first--->last:40 20 33
first--->last:40 20 25 33 77
first--->last:20 25 33 77
对双向链表学的不好的同学。写起来可能比较费劲。我也是一边画图,一边理解。现在记下来以便以后加强记忆。