详细图文——双向链表

前篇->有序链表
       在传统链表中我们寻找下一个结点是否方便,但是如果要追溯前面的结点是比较困难的。
       双向链表提供了反向遍历的能力。其秘密在于每个结点有两个指向其他结点的引用,一个指向前继结点,一个指向后继结点。下图显示了双向链表:
在这里插入图片描述

代码实现双向链表

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&&current.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&&current.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();
	}
}

在这里插入图片描述

原创文章 234 获赞 1294 访问量 23万+

猜你喜欢

转载自blog.csdn.net/qq_25343557/article/details/83720024