Java双向链表

原创 2018年04月15日 14:09:13

双向链表

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


应用场景:

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

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:



版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Bugggget/article/details/79948757

Java学习指南系列(Java快速入门)

-
  • 1970年01月01日 08:00

二叉搜索树与双向链表(java版)

题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 分析:      对于二叉搜索树,用中序搜索...
  • hll174
  • hll174
  • 2016-03-27 22:18:48
  • 1143

Java单双链表的创建、反转与递归反转

Java单双链表的创建、反转与递归反转
  • L_serein
  • L_serein
  • 2011-04-09 01:40:00
  • 4178

《链表》——单向链表和双向链表(Java)

完整的代码地址为:github  点击查看 单链表 单链表包括数据域和指向下一个节点的指针域,其结构如上图所示 首先定义一个数据类: class DATA{ //定义链表的一个...
  • Gamer_gyt
  • Gamer_gyt
  • 2016-05-20 20:03:36
  • 2129

剑指offer:二叉搜索树与双向链表(java)

题目:输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建新的结点,只能调整树中结点指针的指向。 比如如下图中的二叉搜索树,则输出转换之后的排序双向链表为:     由于要...
  • abc7845129630
  • abc7845129630
  • 2016-10-03 22:12:04
  • 364

Java双向链表实现

public class DoublyLinkList { private class Data{ private Object obj; private Data left = null;...
  • a19881029
  • a19881029
  • 2014-04-03 22:42:08
  • 8435

数据结构之双向链表(JAVA实现)

最近重新复习了一些基础的数据结构,发觉自己好多已经淡忘了,索性重新捡起来以前的知识,今天笔者回顾了一下链表的知识,用JAVA实现了一个双向链表,下面来看代码:public class DoubleLi...
  • as02446418
  • as02446418
  • 2015-07-28 23:25:29
  • 2134

JAVA实现双向链表终极解析!!熟练使用接口

双向链表结构和单向链表的区别:最后一个结点的链接地址上,单向链表是null,而双向链表是表头的链接地址。 即双向链表的head和last互相指向 示意图 表头为空       ...
  • defineshan
  • defineshan
  • 2016-08-21 10:35:47
  • 1252

Java 数据结构之双向链表

一、概述:1、什么时双向链表: 链表中的每个节点即指向前面一个节点,也指向后面一个节点,就像丢手绢游戏一样,每个人都手拉手 2、从头部插入 要对链表进行判断,如果为空则设置尾节点为新添加的节...
  • lovoo
  • lovoo
  • 2016-06-27 21:09:10
  • 6827

Java 单链表的反转 以及 双向链表的实现

Java 单链表的反转 双向链表的实现
  • fuckluy
  • fuckluy
  • 2016-03-27 09:34:36
  • 926
收藏助手
不良信息举报
您举报文章:Java双向链表
举报原因:
原因补充:

(最多只允许输入30个字)