之前实现了线性表的数组实现方式,了解了其特性,查询很快,不过才进行元素插入和删除时需要移动元素才能完成。为了避免这种缺点,我们需要在每个单元中设置指针来表示元素之间的逻辑关系,增加了额外的存储空间。用链式存储是以空间为代价换取了时间,其实写代码基本没有绝对的事情,我们总是在寻找最合适的方式处理我们遇到的问题,在时间和空间之间找平衡点,有时候时间要求更多一点,有时候空间要求更多一点,具体情况具体分析。
链表存储数据元素的结构是通过单元的指针串起来形成的,在实际存储中并不像数组一样是连续的存储,链表分为单向链表,双向链表,不论哪种都有数据域和指针,只不过双向链表有前后两个指针,而单向链表只有next指针。链表中的每一个节点都有相同的基本结构。Java中是没有显示的指针类型,然而实际上对象的访问就是使用指针来实现的,使用对象的引用来代替指针。所以在实现节点结构时,节点本身就是对象,指针域next通过节点对象的引用来实现。
节点接口
单链表节点定义
末节点的next为null
链表的第一个节点和最后一个节点,分别称为链表的首节点和尾节点。尾节点也就是末节点的特征是next引用为null,每个节点中的next指向下一个节点,通过next我们可以从首节点移动到尾节点,在单链表中我们通常使用head来指向首节点,由head即可完成对整个链表中所有节点的访问。如果需要也可以用tail引用来进行操作。
与数组类似,单链表中的节点也是一个线性次序,如果P的next引用指向节点s,那么p称为s的直接前驱, s称为p的直接后续。单链表的特性是只能通过前驱找后续,不能通过后续 找前驱。
单链表中进行查找时只能从首节点开始,并通过节点的next引用来访问每个节点进行查找。判断节点的数据域是否与元素e相同。与数组的元素查找一样,需要n/2的时间。
在链表中数据元素的插入,通过在链表中插入数据元素所属的节点来完成,对于链表的不同位置,插入的过程也有些差别,单链表首节点没有直接前驱节点,所以可以直接在首节点之前插入一个新的节点,在其它位置插入时,只能在已知某个特定节点引用的基础上,在其后面插入新节点,如果已知节点,那么插入时需要的时间是常数。所以插入操作比在数组中要快得多。
类似的,删除链表不同位置的节点也不一样,除首节点外必须都要知道节点的直接前驱,在已知某个节点引用的情况下,删除节点需要的时间也是常数,所以删除也比数组快。
通过以上分析,单链表中进行顺序查找与数组中完成操作时间相同,而在单链表中已知特定节点引用的前提下完成数据插入与删除比在数组中要快很多。
链表存储数据元素的结构是通过单元的指针串起来形成的,在实际存储中并不像数组一样是连续的存储,链表分为单向链表,双向链表,不论哪种都有数据域和指针,只不过双向链表有前后两个指针,而单向链表只有next指针。链表中的每一个节点都有相同的基本结构。Java中是没有显示的指针类型,然而实际上对象的访问就是使用指针来实现的,使用对象的引用来代替指针。所以在实现节点结构时,节点本身就是对象,指针域next通过节点对象的引用来实现。
节点接口
package taxus.list;
public interface Node {
//获取节点数据域
public Object getData();
//设置节点数据域
public void setData(Object obj);
}
单链表节点定义
package taxus.list;
public class SLNode implements Node {
private SLNode next;
private Object element;
public SLNode(){
this(null, null);
}
public SLNode(Object ele, SLNode next){
this.element = ele;
this.next = next;
}
public SLNode getNext(){
return next;
}
public void setNext(SLNode next){
this.next = next;
}
public Object getData() {
return element;
}
public void setData(Object obj) {
this.element = obj;
}
}
末节点的next为null
链表的第一个节点和最后一个节点,分别称为链表的首节点和尾节点。尾节点也就是末节点的特征是next引用为null,每个节点中的next指向下一个节点,通过next我们可以从首节点移动到尾节点,在单链表中我们通常使用head来指向首节点,由head即可完成对整个链表中所有节点的访问。如果需要也可以用tail引用来进行操作。
与数组类似,单链表中的节点也是一个线性次序,如果P的next引用指向节点s,那么p称为s的直接前驱, s称为p的直接后续。单链表的特性是只能通过前驱找后续,不能通过后续 找前驱。
单链表中进行查找时只能从首节点开始,并通过节点的next引用来访问每个节点进行查找。判断节点的数据域是否与元素e相同。与数组的元素查找一样,需要n/2的时间。
在链表中数据元素的插入,通过在链表中插入数据元素所属的节点来完成,对于链表的不同位置,插入的过程也有些差别,单链表首节点没有直接前驱节点,所以可以直接在首节点之前插入一个新的节点,在其它位置插入时,只能在已知某个特定节点引用的基础上,在其后面插入新节点,如果已知节点,那么插入时需要的时间是常数。所以插入操作比在数组中要快得多。
类似的,删除链表不同位置的节点也不一样,除首节点外必须都要知道节点的直接前驱,在已知某个节点引用的情况下,删除节点需要的时间也是常数,所以删除也比数组快。
通过以上分析,单链表中进行顺序查找与数组中完成操作时间相同,而在单链表中已知特定节点引用的前提下完成数据插入与删除比在数组中要快很多。