数据结构(java)——单链表、双端链表和双向链表

原创 2018年04月17日 20:56:25

单链表

    链表大家都很熟悉,链表是由若干个节点串起来的一个结构。类似于火车一样,拥有一个头结点(火车头)之后挂着一个个的节点,每个节点后面跟上另一个节点。每个节点分为两个域,一个数据域,用来存放这个节点的数据,一个是节点域,用来存放下一个节点。

    所以对于单链表,用java实现我们首先创建节点类。

Node类:

//联结点,相当于是车厢
public class Node {
	//数据域
	public long data;
	//节点域
	public Node next;
	
	//默认构造方法
	public Node(long value) {
		this.data = value;
	}
	
	//显示方法
	public void display() {
		System.out.print(data + " ");
	}
}

再实现一些链表的基本操作。

LinkList类:

//链表,相当于火车
public class LinkList {
	//车头,头结点
	private Node first;
	
	public LinkList() {
		first = null;
	}
	
	//插入节点,在头结点之后插入
	public void insertFirst(long value) {
		Node aNode = new Node(value);
		aNode.next = first;
		first = aNode;
	}
	
	//删除头节点
	public Node deleteFirst() {
		Node tmp = first.next;
		first = tmp;
		return tmp;
	}
	
	
	//显示方法
	public void display() {
		Node now = first;
		while(now != null) {
			now.display();
			now = now.next;
		}
		System.out.println();
	}
	
	//查找方法
	public Node find(long value) {
		Node now = first;
		while(now.data != value) {
			if(now.next == null) {
				return null;
			}
			now = now.next;
		}
		return now;
	}
	
	//根据数值删除
	public Node delete(long value) {
		Node now = first;
		Node before = first;
		while(now.data != value) {
			if(now.next == null) {
				return null;
			}
			before = now;
			now = now.next;
		}
		
		if(now == first) {
			first = first.next;
		}
		else {
			before.next = now.next;
		}
		return now;
	}
}

对上面一些基础的方法测试:

public class Test {

	public static void main(String[] args) {


		LinkList ll = new LinkList();
		ll.insertFirst(1);
		ll.insertFirst(2);
		ll.insertFirst(3);
		ll.insertFirst(4);
		ll.insertFirst(5);
		
		ll.display();
//		
//		ll.deleteFirst();
//		ll.display();
		
//		ll.find(2).display();
		
//		Node node = ll.delete(2);
//		ll.display();
	}
}

双端链表

双端链表相比于单链表,其实就是加入了一个尾节点来标识表尾

Node类:

//联结点,相当于是车厢
public class Node {
	
	//数据域
	public long data;
	//节点域(后)
	public Node next;
	
	//默认构造方法
	public Node(long value) {
		this.data = value;
	}
	
	//显示方法
	public void display() {
		System.out.print(data + " ");
	}
}

相比于单链表,双端链表在插入和删除等操作时进行了一点小的修改,体现在吧last移动的处理上

FirstLastLinkList类:

//双端链表
public class FirstLastLinkList {
	//车头,头结点
	private Node first;
	//尾节点
	private Node last;
	
	public FirstLastLinkList() {
		first = null;
		last = null;
	}
	
	//插入节点,在头结点之后插入
	public void insertFirst(long value) {
		Node aNode = new Node(value);
		if (isEmpty()) {
			last = aNode;
		}
		aNode.next = first;
		first = aNode;
	}
	
	//尾节点插入
	public void insertLast(long value) {
		Node aNode = new Node(value);
		if (isEmpty()) {
			first = aNode;
		}
		else {
			last.next = aNode;
		}
		last = aNode;
	}
	
	//删除头节点
	public Node deleteFirst() {
		Node tmp = first;
		if (first.next == null) {
			last = null;
		}
		first = tmp.next;
		return tmp;
	}
	
	//显示方法
	public void display() {
		Node now = first;
		while(now != null) {
			now.display();
			now = now.next;
		}
		System.out.println();
	}
	
	//查找方法
	public Node find(long value) {
		Node now = first;
		while(now.data != value) {
			if(now.next == null) {
				return null;
			}
			now = now.next;
		}
		return now;
	}
	
	//根据数值删除
	public Node delete(long value) {
		Node now = first;
		Node before = first;
		while(now.data != value) {
			if(now.next == null) {
				return null;
			}
			before = now;
			now = now.next;
		}
		
		if(now == first) {
			first = first.next;
		}
		else {
			before.next = now.next;
		}
		return now;
	}
	
	//判断是否为空
	public boolean isEmpty() {
		return first == null;
	}
}

针对双端链表的一点测试(大家可以自己使用测测):

public class Test {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		FirstLastLinkList f1 = new FirstLastLinkList();
//		f1.insertFirst(34);
//		f1.insertFirst(56);
//		f1.insertFirst(67);
//		f1.display();
//		
//		f1.deleteFirst();
//		f1.deleteFirst();
//		f1.display();
		
		f1.insertLast(56);
		f1.insertLast(90);
		f1.insertLast(12);
		f1.display();
		
//		f1.delete(12);
//		f1.display();
		while (!f1.isEmpty()) {
			f1.deleteFirst();
			f1.display();
		}
	}
}

双向链表

为了解决尾删这个问题,引入双向链表,在单链表和双端链表中,如果要进行尾部删除,就要吧表遍历一遍,耗时间耗空间。双向链表的每个节点分为3个域,一个数据域,另外两个节点域,既保存前面的节点的信息也保存后面的节点的信息。可以理解为有2个指针,既有next后指针,又有previous前指针。

Node类:

//联结点,相当于是车厢
public class Node {
	
	//数据域
	public long data;
	//节点域(后)
	public Node next;
	//节点域(前)
	public Node previous;
	
	//默认构造方法
	public Node(long value) {
		this.data = value;
	}
	
	//显示方法
	public void display() {
		System.out.print(data + " ");
	}
}

DoubleLinkList类:

//双向链表

public class DoubleLinkList {
	//车头,头结点
	private Node first;
	//尾节点
	private Node last;
	
	public DoubleLinkList() {
		first = null;
		last = null;
	}
	
	//插入节点,在头结点之后插入
	public void insertFirst(long value) {
		Node aNode = new Node(value);
		
		//为空,设置尾节点为新增加的节点
		if (isEmpty()) {
			last = aNode;
		}
		//链表不为空的时候,把插入前第一个节点的previous指向新节点
		else {
			first.previous = aNode;
		}
		aNode.next = first;
		first = aNode;
	}
	
	//尾节点插入
	public void insertLast(long value) {
		Node aNode = new Node(value);
		if (isEmpty()) {
			first = aNode;
		}
		else {
			last.next = aNode;
			aNode.previous = last;
		}
		last = aNode;
	}
	
	//删除头节点
	public Node deleteFirst() {
		Node tmp = first;
		if (first.next == null) {
			last = null;
		}
		else {
			//这里因为存在双指针,所以需要吧后面节点的指向前面节点的那个指针置空
			first.next.previous = null;
		}
		first = tmp.next;
		return tmp;
	}
	
	//删除尾节点
	public Node deleteLast() {
		Node tmp = last;
		if (first.next == null) {
			first = null;
		}
		else {
			//意思同上
			last.previous.next = null;
		}
		last = last.previous;
		return last;
	}
	
	//显示方法
	public void display() {
		Node now = first;
		while(now != null) {
			now.display();
			now = now.next;
		}
		System.out.println();
	}
	
	//查找方法
	public Node find(long value) {
		Node now = first;
		while(now.data != value) {
			if(now.next == null) {
				return null;
			}
			now = now.next;
		}
		return now;
	}
	
	//根据数值删除
	public Node delete(long value) {
		Node now = first;
		while(now.data != value) {
			if(now.next == null) {
				return null;
			}
			now = now.next;
		}
		
		if(now == first) {
			first = first.next;
		}
		else {
			now.previous.next = now.next;
		}
		return now;
	}
	
	//判断是否为空
	public boolean isEmpty() {
		return first == null;
	}
}

对双向链表的基本功能进行一些测试:

public class TestDoubleLinkList {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		DoubleLinkList dL = new DoubleLinkList();
		dL.insertLast(45);
		dL.insertLast(56);
		dL.insertLast(90);
		dL.display();
		
//		dL.deleteLast();
//		dL.display();
		
		while(!dL.isEmpty()) {
			dL.deleteFirst();
			dL.display();
		}
	}

}

数据结构基础系列(5):数组与广义表

-
  • 1970年01月01日 08:00

(Java笔记学习8)双端链表和双向链表

双端链表和双向链表 一、什么是双端链表。       链表中保存着对最后一个链节点引用的链表。 二、从头部进行插入       要对链表进行判断,如果为空则设置尾节点为新添加的节点。 三、从尾部进行插...
  • CoderBruis
  • CoderBruis
  • 2017-02-27 17:02:46
  • 478

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

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

双端链表(不是双向链表)的原理

与单向链表的不同之处在保存有对最后一个链接点的引用(last) insertFirst:在表头插入一个新的链接点,时间复杂度O(1) insertLast:在表尾插入一个新的链接点,时...
  • xlnwrnmdbb
  • xlnwrnmdbb
  • 2017-05-27 14:52:58
  • 236

双链表相比单链表的优点

删除单链表中的某个结点时,一定要得到待删除结点的前驱,得到该前驱有两种方法,第一种方法是在定位待删除结点的同时一路保存当前结点的前驱。第二种方法是在定位到待删除结点之后,重新从单链表表头开始来定位前驱...
  • a_long_
  • a_long_
  • 2016-03-28 17:47:12
  • 1318

Java数据结构和算法——数组、单向链表、双向链表

概要线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列。本文先介绍线性表的几个基本组成部分:数组、单向链表(One-way LinkedList)、双向链表(two-way ...
  • jdsjlzx
  • jdsjlzx
  • 2016-06-21 22:17:42
  • 2222

数据结构与算法Java版——双向链表

今天分享的是双向链表的实现,双向链表其实很容易实现,只需要在节点Node类加一个前置节点的属性,再让其指向上一个节点就可以完成,还要注意的点就是双线链表的查询操作可以从head节点或tail节点开始,...
  • xichang702
  • xichang702
  • 2017-06-23 17:37:10
  • 230

数据结构——使用双端链表实现队列(java实现)

队列是这样一种数据结构:在队尾(rear)插入数据项,在队首(front)移除数据项,队列的进出顺序是先进入的先被移除(先进先出,FIFO);      Robert Lafore的书对队列的使用有...
  • u012288582
  • u012288582
  • 2015-11-27 13:13:02
  • 475

数据结构——循环单链表和双向链表

1.循环单链表 1.循环单链表特点: 链表中最后一个结点的指针域不再是结束标志,而是指向整个链表的第一个结点,从而使链表形成一个环。和单链表相同,循环单链表也有带头结点和不带头结点两种。带头结点的...
  • xiaofei__
  • xiaofei__
  • 2016-03-25 21:57:39
  • 2720

数据结构——线性表 (顺序表、单链表、静态链表、循环链表、双向链表)

线性表 ---顺序存储结构 ---链式存储结构(单链表、静态链表、循环链表、双向链表)...
  • daijin888888
  • daijin888888
  • 2017-04-12 16:06:27
  • 2321
收藏助手
不良信息举报
您举报文章:数据结构(java)——单链表、双端链表和双向链表
举报原因:
原因补充:

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