双链表的实现(首先了解单链表的原理)

双链表

双链表其实和单链表区别不大,与单链表相比,双链表的每个节点是由 一个数据  两个指针组成的,两个指针分别指向前驱和后继。

双链表与单链表相比的一个好处就是,双链表中的任意一个节点都可以比较容易的访问它的前驱和后继

双链表图

双链表的实现

首先先介绍一下双链表的增加和删除一个节点功能的实现

双链表删除增加节点

实现代码

/*
 * 线性表的接口的定义
 */
public interface MyList {
	/*
	 * 增加元素
	 */
	void add(Object element);
	
	/*
	 * 删除元素
	 */
	void delete(Object element);
	//删除指定索引的元素
	void delete(int index);
	
	/*
	 * 更新元素
	 * 修改指定索引的值为新的element
	 */
	void update(int index,Object NewElement);
	
	/*
	 * 查询元素
	 */
	boolean contains(Object target);

	//查找element元素的索引   如果没有返回-1
	int indexOf(Object element);
	
	//返回指定索引的元素
	Object at(int index);
}
public class ListNode {
	 Object data;
	 ListNode next;	 //记录当前访问节点的后面一个节点
	 ListNode pre;   //记录当前访问节点的前面一个节点
	
	public ListNode(Object data){
		this.data = data;
	}
}
/*
 * 双链表的实现
 */
public class doubleLinkedList implements MyList {
	private ListNode first = new ListNode(null);	//头节点   亚元  不存放元素
	private ListNode last = new ListNode(null);	//最后的节点  亚元  不存放元素
	private int size;
	
	public doubleLinkedList()
	{
		first.next = last;
		last.pre = first; 
	}
	//向链表中添加一个节点
	@Override
	public void add(Object element) {
		ListNode newNode = new ListNode(element);
		
		last.pre.next = newNode;
		newNode.next = last;
		newNode.pre = last.pre;
		last.pre = newNode;
		
		size++;
	}
	
	//删除节点
	@Override
	public void delete(Object element) {
		ListNode p = first.next;
		
		while(p!=last)
		{
			if(p.data.equals(element))
			{
				p.pre.next = p.next;
				p.next.pre = p.pre;
				p.next = null;
				p.pre = null;
				size--;
				break;
			}
			p = p.next;
		}
	}
	
	//通过给定的索引值去删除节点 
	//需要考虑的一个问题就是  一直删的话  会不会出现越界问题
	@Override
	public void delete(int index) {
		//先判断索引值 是否在范围内 如果不在话 直接return
		if(index<0||index>=size)
		{
			return;
		}
		ListNode p = first.next;
		int i = 0;			//和每个结点相对应
		
		while(p != last)
		{
			if(i == index)
			{
				p.pre.next = p.next;
				p.next.pre = p.pre;
				p.next = null;
				p.pre = null;
				size--;
				break;
			}
			i++;
			p = p.next;
		}

	}

	@Override
	public void update(int index, Object NewElement) {
		//先判断索引值 是否在范围内 如果不在话 直接return
				if(index<0||index>=size)
				{
					return;
				}
		
		ListNode p = first.next;
		int i = 0;			//和每个结点相对应
		
		while(p != last)
		{
			if(i == index)
			{
				p.data = NewElement;
				break;
			}
			i++;
			p = p.next;
		}
	}

	@Override
	public boolean contains(Object target) {
		ListNode p = first.next;
		while(p != last)
		{
			if(p.data.equals(target))
			{
				return true;
			}
			p = p.next;
		}
		return false;
	}

	@Override
	public int indexOf(Object element) {
		ListNode p = first.next;
		int i = 0;
		while(p!=last)
		{
			if(p.data.equals(element))
			{
				return i;
			}
			i++;
			p = p.next;
		}
		return -1;
	}
	
	@Override
	public Object at(int index) {
		if(index<0||index>=size)
		{
			return null;
		}
		int i = 0;
		ListNode p = first.next;
		
		while(p!=last)
		{
			if(i == index)
			{
				return p.data;
			}
			i++;
			p = p.next;
		}
		return null;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		//遍历 首先需要将头节点先复制一下  不能直接将头节点拿过来使用
		ListNode p = first.next;
		
		while(p!=last)
		{
			sb.append(p.data);
			
			if(p.next!=last)
			{
				sb.append(",");
			}
			p = p.next;
		}
		sb.append("]");
		return sb.toString();
	}
}

测试


public class Test {
	public static void main(String[] args) {
		doubleLinkedList d = new doubleLinkedList();
		d.add("a");
		d.add("b");
		d.add("c");
		d.add("d");
		d.add("e");
		
		System.out.println(d);
		
		d.delete("a");
		System.out.println(d);
		d.delete(1);
		System.out.println(d);
		
	}
}

结果:

[a,b,c,d,e]
[b,c,d,e]
[b,d,e]

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值