为什么使用链表?
数组作为数据存储结构有一定缺陷。无序数组搜索低效,有序数组插入低效;无论哪种数组,删除低效;大小固定,无法所以改变。但是数组的优势是通过下标随机访问各个数据。
链表可以取代数组作为存储数据的基础,比如栈,队列。
链表分类:单链表、双端链表、有序链表、双向链表、有迭代器的链表(迭代器是用来随机访问链表元素的一种方法)。
链结点:每个数据都包含在“链结点”中。一个链结点是Link类对象。因为一个链表中有许多类似的链结点,所以有必要用一个不同于链表的类来表达链结点。每个Link对象都包含一个对下一个链结点的引用的字段(通常是next),链表本身的对象有一个字段指向第一个链结点的引用。
关系,而不是位置!
链表不同于数组的主要特点之一。一个数组中,每一个项占用一个特定的位置。这个位置可以用一个下标号直接访问。在链表中,寻找一个特定元素的唯一方法就是沿着这个元素的链一直向下寻找,不能直接访问到数据项,必须使用数据之间的关系来定位它。
单链表:
/**
* Created by Zhans on 2018/9/11.
* LinkListApp.java
* 单链表
*/
class Link {
public int iData; //数据项(key)
public double dData; //数据项
public Link nextLink; //下一个链结点引用。这种类定义有时叫做“字引用”式,因为它包含了一个和自己类型相同的字段(本列中是nextLink)
public Link(int id, double dd) {
iData = id;
dData = dd;
//这里不需要初始化nextLink字段,因为它被创建时自动赋null值,意味着这个字段不指向任何结点,除非该链结点后来被连接到其他的链结点才改变
}
public void displayLink() {
System.out.print("{" + iData + ", " + dData + "} ");
}
}
/**
* LinkList类中只包含一个数据项:即对链表中第一个链结点的引用,本例中为firstLink。
* 它是唯一的链表需要维护的永久信息,用以定位所有其他的链结点。从firstLink出发,沿着链表通过每个链结点的nextLink字段就可以找他其他的链结点。
*/
class LinkList {
private Link firstLink;
public void LinkList() {
firstLink = null; //当firstLink的值为空时,表示链表中没有数据项。如果有,firstLink字段中应该存有对第一个链结点的引用值
}
public boolean isEmpty() { //判断链表是否为空;
return (firstLink == null);
}
//insertFirst方法作用是在链表表头插入一个新链结点
public void insertFirst(int id, double dd) {
Link newLink = new Link(id, dd);
newLink.nextLink = firstLink; // newLink --> old firstLink
firstLink = newLink; // firstLink --> newLink
}
//deletFirst方法是firstLink方法的逆操作,返回删除的链结点
//注意,deletFirst方法假定链表是不空的。。调用它之前,先调用isEmpty()方法判断链表是否为空
public Link deletFirst() {
Link temp = firstLink;
firstLink = firstLink.nextLink;
return temp;
}
//根据所给关键值查找链结点,假设是非空链表
public Link find(int key) {
Link current = firstLink;
while (current.iData != key) {
if (current.nextLink == null)
return null;
else
current = current.nextLink;
}
return current;
}
//删除所给关键值的链结点
public Link delete(int key) {
Link previous = firstLink;
Link current =firstLink;
while (current.iData != key) {
if (current == null)
return null;
else {
previous = current;
current = current.nextLink;
}
}
if (current == firstLink) {
firstLink = firstLink.nextLink;
} else {
previous.nextLink = current.nextLink;
}
return current;
}
public void displayList() {
System.out.println("List (first --> last):");
Link current =firstLink;
while (current != null) {
current.displayLink();
current = current.nextLink;
}
}
}
class LinkListApp {
public static void main(String[] args) {
}
}