双向链表——Java实现

原创 2018年04月15日 11:06:03

双向链表

链表是是一种重要的数据结构,有单链表和双向链表之分;本文我将重点阐述不带头结点的双向链表:

                                

不带头结点的带链表

我将对双链表的增加和删除元素操作进行如下解析

   1.增加元素(采用尾插法)

(1)链表为空

     新建结点,将头结点first和尾节点last都指向新建结点,尾节点的next指向空。

 

空链表增加元素

(2)链表非空

     先定义一个临时的结点temp保存当前的尾节点,将尾节点last指向新建结点,并将lastprev指向temptempnext指向last.

                                       

非空链表增加元素

2.删除指定下标的元素

我将分以下三种情况进行讨论

(1)要删除元素为头结点

 node保存当前头结点first,并将头结点first指向first.next且将现在的first.prev置为空,将node.nextdata分别置为空。

                                       

删除头结点

(2)要删除元素为尾节点

      用节点node保存当前的尾节点,将last指向当前尾节点的前一个节点last.prev,并将现last.next置为空,将以前的lastnode节点的prevdata置空。

  

删除尾结点

(3)要删除元素为中间节点

      用节点node保存要删除的节点,并将要删除节点的前一个节点的next指向要删除节点的下一个节点;要删除节点的下一个节点的prev指向要删除节点的还是那个一个节点;即node.prev. next = node.nextnode.next.prev = node.prev。并将要删除节点的prevnextdata置为null.

                              

删除中间结点

package Struct;

interface Link{
	void add(Object obj);
	boolean remove(int index);
	boolean contain(Object obj);
	int indexOf(Object obj);
	boolean set(int index,Object obj);
	Object get(int index);
	int length();
	void clear();
	Object[] toArray();
	void printArray(Object[] obj);
	void printLink();
}
class Factory{
	private Factory(){}
	public static Link getLinkInstance(){
		return new LinkImpl();
	}
}
class LinkImpl implements Link{
	private Node first;
	private Node last;
	private int size;
	private class Node{
		private Node prev;
		private Node next;
		private Object data;
		public Node(Object data){
			this.data = data;
		}
	}
	public void add(Object obj) {
		//要插入元素为空
		if(obj == null){
			return;
		}
		Node node = new Node(obj);
		//空链表
		if(first == null){
			first = last = node;
			first.next = null;
			size++;
		}else{
		//非空链表(尾插)
			Node temp = this.last;
			temp.next = node;
			last = node;
			last.prev = temp;
			size++;
		}
	}
	//删除
	public boolean remove(int index) {
		//指定下标不合法
		if(index >= size){
			return false;
		}
		Node node = first;
		//要删除的节点为头结点
		if(index == 0){
			first = node.next;
			first.prev = null;
			node.prev = node.next = null;
			node.data = null;
			size--;
			return true;
		}
		//要删除节点为尾节点
		if(index == size-1){
			Node node1 = last;
			last = node1.prev;
			last.next = null;
			node1.prev = node1.next = null;
			node1.data = null;
			size--;
			return true;
		} 
		//要删除节点为中间节点
			Node node3 = get(index);
			node3.prev.next = node3.next;
			node3.next.prev = node3.prev;
			node3.prev = node3.next = null;
			node3.data = null;
			size--;
			return true;
	}
	//查看元素是否包含在链表中
	public boolean contain(Object obj) {
		//空链表
		if(first == null&&first.next==null){
			return false;
		}
		for(Node node = first;node!=null;node=node.next){
			if(node.data==obj){
				return true;
			}
		}
		return false;
	}
	//求取元素obj的下标
	public int indexOf(Object obj) {
		Node node  = first;
		int signal = 0;
		//空链表
		if(first== null&& first.next == null){
			return -1;
		}else{
			for(node = first;node!=null;node=node.next){
				if(node.data == obj){
					return signal;
				}
				signal++;
			}
		}
		return signal;
	}
	//修改index处的值为obj
	public boolean set(int index, Object obj) {
		//指定位置不存在
		if(index<0||index >= size){
			return false;
		}
		//指定下标超过链表长度
		if(index >= size){
			return false;
		}
		Node node = first;
		//若链表头结点是要修改的元素
		if(node == get(index)){
			node.data = obj;
		}
		Object getObject = get(index);
		for(node = first;node !=null;node=node.next){
			if( getObject == node){
				node.data = obj;
			}
		}
		return true;
	}
	//取得index处的元素
	public Node get(int index) {
		if(first==null&&first.next==null){
			return null;
		}
		//要查找下标不在范围内
		if(index >= size){
			return null;
		}
		Node node = first;
		//要查找元素在中间元素的左侧
		if(index >=0 && index <= (index<<1)){
			for(int i = 0;i <= index - 1;i++){
				if(i == index){
					return node;
				}
				node =node.next;
			}
		}
		else if(index > (index<<1)){
        //要查找元素在中间元素的右侧
			for(int i = index; i < size-1;i++){
				if(i == index){
					return node;
				}
				node = node.next;
			}
		}
			return node;
	}
	//求链表长度
	public int length() {
		//空链表
		if(first == null){
			return 0;
		}
		return this.size;
	}
	//清空链表
	public void clear() {

		Node node = first;
		if(first == null && first.next == null){
			return;
		}
		for(node = first.next;node!=null;){
			Node temp = node;
			node.prev = node.next = null;
			node.data = null;
			node = node.next;
			size--;
		}
		first.next = null;
		first.data = null;
		size--;
	}
	//将链表转换成Object数组
	public Object[] toArray() {
		//空链表
		if(first == null && first.next == null){
			return null;
		}else{
			Object[] linkObject = new Object[this.size];//向上转型
			Node node = first;
			for(int i = 0;i<size;i++){	
				linkObject[i] = node.data;
				node = node.next;
				}
			return linkObject;
		}
	}
	//打印Object数组
	public void printArray(Object[] obj){
		for(int i = 0;i < obj.length;i++){
			System.out.print(obj[i]+" <-> ");
		}
	}
	//打印链表
	public void printLink() {
		Node node = first;
		for(node = first;node!=null;node=node.next){
			System.out.print(node.data+" <——> ");
		}
		System.out.println();
	}
	
}
public class DoubleLinkList {
	public static void main(String[] args) {
		Link link = Factory.getLinkInstance();
		System.out.println("\n"+"=================以下为add测试函数===================");
		link.add("我是开始位置");
		link.add("第一名");
		link.add("第二名");
		link.add("第三名");
		link.add("我是结束位置");
		System.out.println("\n"+"===============以下为printLink测试函数===============");
		link.printLink();
		System.out.println("\n"+"===============以下为indexOf测试函数================");
		System.out.println(link.indexOf("第二名"));
		System.out.println(link.indexOf("我是结束位置"));
		System.out.println("\n"+"===============以下为contain测试函数================");
		System.out.println(link.contain("我是结束位置"));
		System.out.println(link.contain("hahh"));
		System.out.println("\n"+"===============以下为get测试函数================");
		System.out.println(link.get(0));
		System.out.println(link.get(4));
		System.out.println(link.get(2));
		System.out.println(link.get(8));
		System.out.println("\n"+"===============以下为length测试函数================");
		System.out.println(link.length());
		System.out.println("\n"+"===============以下为set测试函数===================");
		System.out.println(link.set(0, "我是特等奖"));
		link.printLink();
		System.out.println("\n"+"===============以下为toArray测试函数===================");
		Object[] linkObj = link.toArray();
		System.out.println("\n"+"===============以下为printArray测试函数===================");
		link.printArray(linkObj);
		System.out.println("\n"+"===============以下为remove测试函数===================");
		//删除尾节点
		System.out.println(link.remove(4));
		link.printLink();
		//删除头结点
		System.out.println(link.remove(0));
		link.printLink();
		//删除中间节点
		System.out.println(link.remove(1));
		link.printLink();
		System.out.println(link.length());
		System.out.println("\n"+"===============以下为clear测试函数===================");
		link.clear();
		System.out.println(link.length());
	}
}
测试结果:


Java双向链表实现

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

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

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

Java 实现双向链表,基于双向链表实现双端队列

双向链表: 就是有双向指针 即 双向的链域 链结点的结构: ┌────┬────┬────────┐ │data│next│previous│ └────┴────┴────────┘ 双向链表不必...
  • jjwwmlp456
  • jjwwmlp456
  • 2014-10-26 00:29:49
  • 4749

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

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

java实现双向链表的操作

单向链表只能单方向的查找链表中的节点,并且在插入或者删除某一个节点的时候,必须知道其的前一个节点。当单向链表的前一个节点指向这个链表的第一个节点的时候称为循环链表。 双向链表的每个结构分为三个部分,...
  • liuwei0604
  • liuwei0604
  • 2013-04-25 07:15:23
  • 707

双向链表的Java实现,以及相关函数的实现

1.定义一个节点类 public class Node { //存储的数据 private Object data; //前一个节点 private Node prev; //后一个...
  • daguairen
  • daguairen
  • 2016-10-06 10:10:42
  • 1073

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

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

java 单链表和双向链表的实现

  • 2013年08月06日 17:43
  • 10KB
  • 下载

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

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

实现一个双向链表的倒置功能(1->2->3 变成 3->2->1)

  • 2018年04月15日 13:41
  • 6KB
  • 下载
收藏助手
不良信息举报
您举报文章:双向链表——Java实现
举报原因:
原因补充:

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