Java双向链表

双向链表

         双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。


应用场景:

发布订阅机制,客户端维护,列表键底层实现之一,等等

java双链表实现:

DLinkList.java

package cn.ltp.dlinklist;

/**
 * 双向链表
 * @author Z7M-SL7D2
 *
 */
interface DLinkList {
	
	/**
	 * 添加节点
	 * @param data 节点的数据
	 */
	void add(Object data);
	
	/**
	 * 删除节点
	 * @param data 节点的数据
	 */
	void remove(Object data);
	
	/**
	 * 修改位于index位置的节点
	 * @param index 节点所在位置
	 * @param data 节点的数据
	 */
	void set(int index, Object data);
	
	/**
	 * 获取位于index位置节点的数据
	 * @param index 节点所在位置
	 * @return
	 */
	Object get(int index);
	
	/**
	 * 获取节点个数
	 * @return
	 */
	int getSize();
	
	/**
	 * 获取一个节点
	 * @param index 节点所在位置
	 * @return
	 */
	Object node(int index);
	
	/**
	 * 是否包含某个节点
	 * @param data 数据
	 * @return
	 */
	boolean contains(Object data);
	
	/**
	 * 打印节点
	 */
	void printList();
	
	/**
	 * 判空
	 * @return
	 */
	boolean isEmpty();
	
	/**
	 * 清空
	 */
	void clear();
	
	/**
	 * 转数组
	 * @return
	 */
	Object[] toArray();
	
}

DLinkListImpl.java

package cn.ltp.dlinklist;

public class DLinkListImpl implements DLinkList {
	
	private Node first;
	private Node last;
	int size;
	
	class Node{
		private Node next;
		private Node prev;
		private Object data;
		
		public Node(Node next, Node prev, Object data) {
			super();
			this.next = next;
			this.prev = prev;
			this.data = data;
		}
		
	}

	@Override
	public void add(Object data) {
		if(first == null) {
			Node node = new Node(null, null, data);
			first = node;
			last = node;
		}else {
			Node node = new Node(null, last, data);
			last.next = node;
			last = node;
		}
		this.size++;
		
	}

	@Override
	public void remove(Object data) {
		if(data == null) {
			for(Node cur = this.first; cur != null;) {
				Node tmp = cur.next;
				if(cur.data == null) {
					if(cur == first) {
						if(cur == last) {
							cur = null;
						}else {
							first = cur.next;
							cur.next = null;
							cur = null;
							first.prev = null;
							cur = first;
						}
					}else if(cur == last) {
						last = cur.prev;
						cur.prev = null;
						cur = null;
						last.next = null;
						cur = tmp;
					}else {
						cur.prev.next = cur.next;
						cur.next.prev = cur.prev;
						cur.next = null;
						cur.prev = null;
						cur = null;
						cur = tmp;
					}
					this.size--;
				}else {
					cur = cur.next;
				}
			}
		}else {
			for(Node cur = this.first; cur != null;) {
				Node tmp = cur.next;
				if(data.equals(cur.data)) {
					if(cur == first) {
						if(cur == last) {
							cur = null;
						}else {
							first = cur.next;
							cur.next = null;
							cur = null;
							first.prev = null;
							cur = first;
						}
					}else if(cur == last) {
						
						last = cur.prev;
						cur.prev = null;
						cur = null;
						last.next = null;
						cur = tmp;
					}else {
						
						cur.prev.next = cur.next;
						cur.next.prev = cur.prev;
						cur.next = null;
						cur.prev = null;
						cur = null;
						cur = tmp;
					}
					this.size--;
				}else {
					cur = cur.next;
				}
			}
		}
	}

	@Override
	public void set(int index, Object data) {
		Node node = (Node)node(index);
		if(node != null)
			node.data = data;
	}

	@Override
	public Object get(int index) {
		Node node = (Node)node(index);
		if(node != null) 
			return node.data;
		else {
			try {
				throw new NullPointerException();
			} catch (NullPointerException e) {
				System.out.println("Null:no such element");
				return null;
			}
			
		}
		
	}

	@Override
	public int getSize() {
		return this.size;
	}

	@Override
	public Object node(int index) {
		if(index >= this.size)
			return null;
		int len = this.size;
		if(index < len) {
			if(index > len/2) {
				Node cur = last;
				int step = len - index - 1;
				while(step-->0) {
					cur = cur.prev;
				}
				return cur;
			}else {
				Node cur = first;
				int step = index;
				while(step-->0) {
					cur = cur.next;
				}
				return cur;
			}
		}
		return null;
	}

	@Override
	public void printList() {
		int count = this.size;
		Node cur = first;
		System.out.print("打印链表元素:");
		while(count-- > 0) {
			System.out.print("  " + cur.data);
			cur = cur.next;
		}
		System.out.println();
	}

	@Override
	public boolean contains(Object data) {
		if(data == null) {
			for(Node cur = this.first; cur != null; cur = cur.next) {
				if(cur.data == null)
					return true;
			}
		}else {
			for(Node cur = this.first; cur != null; cur = cur.next) {
				if(data.equals(cur.data))
					return true;
			}
		}
		return false;
	}

	@Override
	public boolean isEmpty() {
		return this.size <= 0;
	}

	@Override
	public void clear() {
		Node cur = first;
		Node tmp = null;
		while(cur != null) {
			tmp = cur.next;
			cur.next = null;
			cur.prev = null;
			cur = tmp;
		}
		first = last = null;
		this.size = 0;
	}

	@Override
	public Object[] toArray() {
		if(size <= 0)
			return null;
		
		Object[] arr = new Object[this.size];
		int i = 0;
		
		for(Node cur = first; cur != null; cur = cur.next, i++)
			arr[i] = cur.data;
			
		return arr;
	}

}

Factory.java

package cn.ltp.dlinklist;

public class Factory {
	public DLinkList getInstance() {
		return new DLinkListImpl();
	}
}

Test.java

package cn.ltp.dlinklist;

public class Test {

	public static void main(String[] args) {
		Factory factory = new Factory();
		DLinkList dList = factory.getInstance();
		dList.add(6);
		dList.add(2);
		dList.add(3);
		dList.add(6);
		dList.add(5);
		dList.add(6);
		dList.add(6);
		dList.add(null);
		dList.add(6);
		dList.add(null);
		dList.printList();
		
		System.out.println("是否包含元素100:" + dList.contains(100));
		System.out.println("第9个元素为" + dList.get(9));
		
		System.out.println("删除链表为空的元素:");
		dList.remove(null);
		dList.printList();
		
		System.out.println("删除链表为6的元素:");
		dList.remove(6);
		dList.printList();
		Object[] arr = dList.toArray();
		
		System.out.println("转数组");
		for(Object object : arr)
			System.out.print(object + " ");
		
		System.out.println("\n清空数组");
		dList.clear();
		dList.printList();
	}
}

result:



  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值