双向链表
单链表有一个很蛋疼的问题就是沿着链路反向遍历是困难的。我们用
1 current=current.next 能很方便的移动到下一个结点,但是我们要反向移动到上一个结点,却没有对应的方法,在应用中,这个限制可能会引起问题。如果我要向上移动,就必须把current变量移到表头,然后在往下一个个遍历,这样的话效率就会非常低。
双向链表提供了这种能力。它既能想钱遍历,也能向后遍历。与单向的区别就是,在Link类中添加一个指向前一个结点的previous字段。
Link类定义
1 public class Link { 2 public int data; 3 public Link next;//指向后一个结点 4 public Link previous;//指向前一个结点 5 public Link(int key){ 6 this.data=key; 7 } 8 }
DoublyLinked类的方法
定义
1 class DoublyLinked{ 2 private Link first; //指向第一个结点 3 private Link last; //指向最后一个结点 4 public DoublyLinked(){ 5 first=null; 6 last=null; 7 } 8 //判断是否为空 9 public boolean isEmpty(){ 10 return first==null; 11 } 12 }
遍历
从左到右遍历和单向链表的遍历方法一样
displayLeft()
public void displayLeft(){ Link current=first;//从第一个开始遍历 System.out.println("从左到右"); while(current!=null){ current.displayList(); current=current.next; } System.out.println("end"); }
从右到左遍历
dispalyRight()
1 public void displayRight(){ 2 Link current=last; 3 System.out.println("从右到左"); 4 while(current!=null){ 5 current.displayList(); 6 current=current.previous; 7 } 8 System.out.println("end"); 9 }
insertFirst() 表头插入链结点
1 public void insertFirst(int key){ 2 Link newLink=new Link(key); 3 if(isEmpty()){ 4 last=newLink;//如果链表为空,last必须改变 5 }else{ 6 first.previous=newLink;//下一个结点指向新增的结点 7 } 8 newLink.next=first;//指向下一个结点 9 first=newLink;//修改first所指向的结点 10 }
insertLast() 表尾插入链结点
1 public void insertLast(int key){ 2 Link newLink=new Link(key); 3 if(isEmpty()){ 4 first=newLink; 5 6 }else{ 7 last.next=newLink; 8 newLink.previous=last; 9 } 10 11 last=newLink; 12 }
insertAfter() 在某个特定的值背后插入新的链接点
1 public boolean insertAfter(int key,int addData){ 2 Link current=first; 3 //先找到链表中是否有该值 4 while(current.data!=key){ 5 current=current.next; 6 if(current==null){ 7 System.out.println("不存在"+key); 8 return false; 9 } 10 } 11 Link newLink=new Link(addData); 12 if(current==last){ 13 newLink.next=null;//如果是表位,则next为空 14 last=newLink; 15 }else{ 16 newLink.next=current.next; 17 current.next.previous=newLink; 18 } 19 current.next=newLink; 20 newLink.previous=current; 21 return true; 22 }
deleteKey(key)删除特定的值
1 public Link deleteKey(int key){ 2 //先寻找结点 3 Link current=first; 4 while(current.data!=key){ 5 current=current.next; 6 if(current==null){ 7 System.out.println("不存在"+key); 8 return null; 9 } 10 } 11 if(current==first){ 12 first=current.next; 13 }else{ 14 current.previous.next=current.next; 15 } 16 if(current==last){ 17 last=current.previous; 18 19 }else{ 20 current.next.previous=current.previous; 21 } 22 return current; 23 }
下面是完整代码
1 public class Link { 2 public int data; 3 public Link next;//指向后一个结点 4 public Link previous;//指向前一个结点 5 public Link(int key){ 6 this.data=key; 7 } 8 public void displayList(){ 9 System.out.println("数据为"+data); 10 } 11 } 12 class DoublyLinked{ 13 private Link first; //指向第一个结点 14 private Link last; //指向最后一个结点 15 public DoublyLinked(){ 16 first=null; 17 last=null; 18 } 19 //判断是否为空 20 public boolean isEmpty(){ 21 return first==null; 22 } 23 public void displayLeft(){ 24 Link current=first;//从第一个开始遍历 25 System.out.println("从左到右"); 26 while(current!=null){ 27 current.displayList(); 28 current=current.next; 29 } 30 System.out.println("end"); 31 } 32 public void displayRight(){ 33 Link current=last; 34 System.out.println("从右到左"); 35 while(current!=null){ 36 current.displayList(); 37 current=current.previous; 38 } 39 System.out.println("end"); 40 } 41 public void insertFirst(int key){ 42 Link newLink=new Link(key); 43 if(isEmpty()){ 44 last=newLink;//如果链表为空,last必须改变 45 }else{ 46 first.previous=newLink;//下一个结点指向新增的结点 47 } 48 newLink.next=first;//指向下一个结点 49 first=newLink;//修改first所指向的结点 50 } 51 public void insertLast(int key){ 52 Link newLink=new Link(key); 53 if(isEmpty()){ 54 first=newLink; 55 56 }else{ 57 last.next=newLink; 58 newLink.previous=last; 59 } 60 61 last=newLink; 62 } 63 public boolean insertAfter(int key,int addData){ 64 Link current=first; 65 //先找到链表中是否有该值 66 while(current.data!=key){ 67 current=current.next; 68 if(current==null){ 69 System.out.println("不存在"+key); 70 return false; 71 } 72 } 73 Link newLink=new Link(addData); 74 if(current==last){ 75 newLink.next=null;//如果是表位,则next为空 76 last=newLink; 77 }else{ 78 newLink.next=current.next; 79 current.next.previous=newLink; 80 } 81 current.next=newLink; 82 newLink.previous=current; 83 return true; 84 } 85 public Link deleteKey(int key){ 86 //先寻找结点 87 Link current=first; 88 while(current.data!=key){ 89 current=current.next; 90 if(current==null){ 91 System.out.println("不存在"+key); 92 return null; 93 } 94 } 95 if(current==first){ 96 first=current.next; 97 }else{ 98 current.previous.next=current.next; 99 } 100 if(current==last){ 101 last=current.previous; 102 103 }else{ 104 current.next.previous=current.previous; 105 } 106 return current; 107 } 108 }
1 public class Test { 2 public static void main(String[] args) { 3 DoublyLinked doubleLink=new DoublyLinked(); 4 doubleLink.insertFirst(1); 5 doubleLink.insertLast(2); 6 doubleLink.insertAfter(1, 3); 7 doubleLink.displayLeft(); 8 doubleLink.displayRight(); 9 doubleLink.deleteKey(3); 10 doubleLink.displayLeft(); 11 } 12 }
从左到右
数据为1
数据为3
数据为2
end
从右到左
数据为2
数据为3
数据为1
end
从左到右
数据为1
数据为2
end