您的位置:首页 > 理论基础 > 数据结构算法

数据结构(java)——单向链表

2013-03-11 11:09 316 查看
一、以整形数据为例的单向链表数据结构的定义:

public class IntNode {
public int info;//info域用来存储信息
public IntNode next;//next域用来存储指向下一个地址的引用
/**
* 构造函数,只有一个参数,利用this通过把第二个参数置空来
* 调用第二个构造函数
* @param i
*/
public IntNode(int i){
this(i,null);
}
/**
* 构造函数,参数为数据域和引用域
* @param i
* @param n
*/
public IntNode(int i,IntNode n){
info=i;next=n;
}
}


二、单项链表的常用操作和注意事项

public class IntSLList {
private IntNode head,tail;//定义IntNode结构的表头和表尾
/**
* 构造函数,初始化单链表
*/
public IntSLList(){
head=tail=null;
}
/**
* 判断单链表是否为空,返回head==null的判断结果
* @return
*/
public boolean isEmpty(){
return head==null;
}
/**
* 表头插入
* @param el
*/
public void addToHead(int el){
head=new IntNode(el,head);//初始化节点,info域存入数值,next域指向head的当前值,head指向新节点
if(tail==null)//特殊情况,当链表为空时,head和tail都指向新节点(唯一不为空节点)
tail=head;
}
/**
* 表尾插入
* @param el
*/
public void addToTail(int el){
if(!isEmpty()){//如果链表不为空
tail.next=new IntNode(el);//初始化节点,调用构造函数一,info域赋值el,next域置空
tail=tail.next;//tail指向当前tail的下一个节点
}else{
head=tail=new IntNode(el);
//如何链表为空,tail是一个不存在节点,不存在域的空引用(指针)
}
}
/**
* 删除表头节点,并返回它的值
* 删除表头节点时,要判断表是否为空,做好空指针异常的处理
* 一种方法是捕获异常,对于删除空表时出现的空指针异常,将其捕获,并进行相关处理
* 另一种方法是在调用删除操作时判断链表是否为空
* 删除表头节点,只是将head的指针指向了下一个节点,这样就无法访问原有表头节点,单原有表头节点仍旧可以指向下一个节点
* 只是因为无法直接访问原有节点,所以该节点被废弃,随后由垃圾回收器来处理
* @return
*/
public int deleteFromHead(){
int el=head.info;//取出表头节点的值
if(head==tail)//这不是表不为空的判断,而是假定链表中只有一个节点,删除该节点时,需将head和tail指针都置空
head=tail=null;
else
head=head.next;
return el;
}
/**
* 删除表尾节点,并返回它的值
* @return
*/
public int deleteFromTail(){
int el=tail.info;
if(head==tail)//如果表中只有一个节点
head=tail=null;
else{
IntNode temp;//因为删除表尾节点,tail需向后移,但是tail没有直接前驱的指针,所以必须依靠临时节点temp
for(temp=head;temp.next!=tail;temp=temp.next);
//temp初始化为表头指针,循环每重复一次,它都指向下一个节点,直到tail前为止,这样就找到了tail的直接前驱
//节点,将直接前驱节点赋值给tail,这也是最耗时的操作,是时间复杂度为O(n)的主要原因
tail=temp;
tail.next=null;//尾节点的next域为空
}
return el;
}
/**
* 打印链表
*/
public void printAll(){
for(IntNode temp=head;temp!=null;temp=temp.next)
System.out.println(temp.info+"  ");
}
/**
* 判断el是否在单链表中——查找
* @param el
* @return
*/
public boolean isInList(int el){
IntNode temp;
for(temp=head;temp.info!=el&&temp!=null;temp=temp.next);
return temp!=null;
}
/**
* 删除链表中的任意位置的值
* @param el
*/
public void delete(int el){
if(!isEmpty()){
if(head==tail&&el==head.info)//如果只有一个节点,并且该节点就是el
head=tail=null;
else if(el==head.info)//如果el位于表头
head=head.next;
else{
IntNode pred,temp;//定义临时节点和它的前驱节点
for(pred=head,temp=head.next;
temp!=null&&temp.info!=el;
pred=pred.next,temp=temp.next);
//利用for循环从表头逐一开始查找,始终保持pred为temp的直接前驱节点,如果未找到el,表不删除任何节点,无操作
//如果找到:
//1、该节点位于表中央,temp的前驱节点直接指向temp的下一个节点,temp节点被废弃
if(temp!=null){
pred.next=temp.next;
//2、如果该节点位于表尾,表尾指针tail指向temp的直接前驱节点
if(temp==tail)
tail=pred;
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: