本篇主要介绍一种新的数据存储结构——链表。链表可能是继数组之后第二种使用得最广泛的通用存储结构。
链表的机制灵活,用途广泛,适用于许多通用数据库。它也可以取代数组,作为其他存储结构的基础,例如栈,队列。除非需要频繁通过下标随机访问各个数据,否则在很多使用数组的地方都可以用链表代替。
链结点
在链表中,每个数据项都被包含在“链结点”(Link)中。一个链结点是某个类的对象,这个类可以叫做Link。因为一个链表中有许多类似的链结点,所以有必要用一个不同于链表的类来表达链结点。每个Link对象中都包含一个对下一个链结点引用的字段(通常叫做next)。但是链表本身的对象中有一个字段指向对第一个链结点的引用。如下图所示,显示了这个关系:
下面是一个Link类定义的一部分。它包含了一些数据和下一个链结点的引用:
class Link {
public int data;
public int idata;
public Link next;//对下一个链结点的引用
}
这种类定义有时候叫做“自引用”式,因为它包含了一个和自己类型相同的字段(本例中叫做next)。
链结点中仅仅包含两个数据项,data和idata。但是在真正应用中,可能包含更多数据项。通常,如果数据项很多的话,可以用一个包含这些数据项的类来替代这些数据项。例如,一个人的姓名,电话,身份证号,性别等,可以使用一个Person对象来替代:
class Link {
public Person person;
public Link next;
}
单链表
//Link类的数据结构
class Link {
public int data;
public int idata;
public Link next;
//带参构造函数
public Link(int id, int da) {
idata=id;
data=da;
}
//显示节点的信息
public void displayLink(){
System.out.println("{"+idata+","+data+"}");
}
}
//LinkList数据结构
class ListLink{
private Link first; //对链表中第一个链结点的引用
public ListLink() {
first=null;
}
//是否为空链表
public boolean isEmpty(){
return (first==null);
}
public void insertFirst(int id,int data){
//先给新的链分配空间
Link newLink = new Link(id, data);
newLink.next = first;
first = newLink;
}
public Link deleteFirst(){
Link temp = first;
first = first.next;
return temp;
}
//第一种查找方法
public Link find_me(int id){
Link current = first;
while(current!=null ){
if(current.idata==id)
return current;
else
current = current.next;
}
return null;
}
//第二种查找方法
public Link find(int key){
Link current = first;
while(current.idata!=key){
if(current.next==null)
return null;
else
current = current.next;
}
return current;
}
public Link delete(int key){
Link previous = first;
Link current = first;
//找到需要删除的节点
while(current.idata!=key){
if(current.next==null)
return null;
else{
previous = current; //对前一个Link的引用
current = current.next;
}
}
if(current==first) //首节点
first = first.next;
else //非首节点
previous.next=current.next;
return current;
}
//打印出LinkList
public void displayList(){
System.out.println("first-->last");
Link current =first;
while(current!=null){
current.displayLink();
current=current.next;
}
System.out.println(" ");
}
}
//main
public class LinkList {
public static void main(String[] args) {
ListLink theList= new ListLink();
//插入链结点 头插法
theList.insertFirst(22, 299);
theList.insertFirst(44, 499);
theList.insertFirst(66, 699);
theList.insertFirst(88, 899);
theList.displayList();
//查找id为33的链结点
Link find_id = theList.find(33);
//如果找到
if(find_id!=null)
System.out.println("find_id = "+find_id.idata);
//未找到