版权声明:聂CC~ https://blog.csdn.net/ncc1995/article/details/86719707
啊,写完了双端之后,双向就好写多了,重点是改变结点的next指向的时候,一定要一起把previous改了,并且要注意可能在last结点处进行指向修改时存在的的null情况。
package linkList;
/*
* 结点定义
*/
class doublyNode{
Object data;
doublyNode next;
doublyNode previous;
public doublyNode(Object d) {
this.data = d;
this.next = null;
this.previous = null;
}
public void display() {
System.out.print(data + " ");
}
}
/*
* 写一个双向链表
*/
public class doublyList {
doublyNode first;
doublyNode last;
public doublyList() {
this.first = null;
this.last = null;
}
/*
* 从头插入结点
*/
public void insertFirst(Object d) {
doublyNode newNode = new doublyNode(d);
if(isEmpty()) {
last = newNode;
}else {
first.previous = newNode;
}
newNode.next = first;
first = newNode;
}
/*
* 从尾部插入结点
*/
public void insertLast(Object d) {
doublyNode newNode = new doublyNode(d);
if(isEmpty()) {
first = newNode;
}else {
last.next = newNode;
//放外边试试
newNode.previous = last;
}
last = newNode;
}
/*
*双向链表的插入操作注意点 :
* (1) 通用的:采用方法为定位到location-1处,所以第一个位置的插入要单独操作
* (2) 此次采用的方法是遍历所有结点,找到对应位置后插入,返回。
* (3) 插入操作时,只需注意在尾部插入时last结点的变化,而不像删除时还要考虑
* 插入第一个结点时last的变化。
* (4) 当在尾部插入时,current.next为null,所以不需要改变其previous。
* (5) 改变next指向时,一定要同时改变previous指向。
*/
public void insertLoc(int loc, Object d) {
int j = 1;
doublyNode current = first;
doublyNode newNode = new doublyNode(d);
if(loc<1 || loc>length()+1) {
System.out.println("The location is not exit!");
return;
}
if(j == loc) {
newNode.next = current;
current.previous = newNode;
first = newNode;
return;
}
while(current != null) {
if(j == loc-1) {
System.out.println(current.data);
newNode.next = current.next;
if(current == last) {
last = current.next;
}else {
current.next.previous = newNode;
}
//这条语句已经将current的next指向改变了,所以不能将else后面的语句写在它后面
current.next = newNode;
newNode.previous = current;
return;
}
current = current.next;
j++;
}
}
/*
* 任意位置删除
*/
public void deleteLoc(int loc) {
doublyNode current = first;
int j = 1;
if(loc<1 || loc>length()) {
System.out.println("delete ERROR!");
return;
}
if(j == loc) {
if(first == last) {
last = null;
}
//将current的值赋给first,first就把current的next,previous等等都继承了
//所以要将first.previous改为null
first = current.next;
first.previous = null;
return;
}
while(current.next != null) {
if(j == loc-1) {
if(current.next == last) {
//改变last之前,last还是在和其它结点相连,
//所以不改变last的话,还是会输出原来的链表
//last = current.next;
last = current;
}else {
current.next.next.previous = current;
}
current.next = current.next.next;
return;
}
current = current.next;
j++;
}
}
/*
* 从头打印链表
*/
public void displayFirst() {
doublyNode current = first;
while(current != null) {
current.display();
current = current.next;
}
System.out.println();
}
/*
* 从尾部开始打印链表
*/
public void displayLast() {
doublyNode current = last;
while(current != null) {
current.display();
current = current.previous;
}
System.out.println();
}
public boolean isEmpty() {
return (first == null);
}
public int length() {
int length = 0;
doublyNode temp = first;
while(temp != null) {
length++;
temp = temp.next;
}
return length;
}
/*
* 测试双端链表
*/
public static void main(String[] args) {
doublyList list = new doublyList();
list.insertFirst(1);
list.insertFirst("cc");
list.insertFirst("hi");
list.displayFirst();
list.displayLast();
list.deleteLoc(3);
list.displayFirst();
list.displayLast();
}
}