链表
最近看了《Data Structures and Other Objects》,感觉收获良多,在此简单做些读书笔记。
1.当链表还没有包含任何结点的时候,链表中的引用变量head和tail都是空引用,表示该链表是空链表。
2.当某个引用变量声明且还没有引用任何对象的时候,可以被初始化为空引用。
3.最后一个结点的link的引用为null。
//一个简单的链表结构实现
public class IntNode{
private int data; //存放链表结点的数据
private IntNode link; //存放下个结点的引用
//初始化一个结点
public IntNode(int initialData, IntNode initialLink){
this.data = initialData;
this.link = initialLink;
}
//获取当前结点的数据
public int getData(){
return this.data;
}
//获取下个结点的引用
public IntNode getLink(){
return this.link;
}
//修改当前结点的数据
public void setData(int newData){
this.data = newData;
}
//修改当前结点的引用
public void setLink(IntNode newLink){
this.link = newLink;
}
}
简单的一个linkList就是能够建立一个结点,同时有获取数据和修改数据的方法
为了便于使用,当然还要能够添加结点、删除结点
//在现有结点后面新增一个结点
public void addNodeAfter(int element){
link = new IntNode(element,link);
}
//删除结点后面的一个结点
public void removeNodeAfter(){
link = link.link;
}
有了添加、删除的操作,操作链表就更加方便了。现在我们再定义一个查找的方法,可以是查找某个元素,也可以是查找某个位置上的元素。
//查找某个元素,通过遍历链表的方式
public static IntNode listSearch(IntNode head, int target){
IntNode point;
for(point = head; point != null; point = point.link){
if(target == point.data)
return point;
}
return null;
}
//指定位置查找某个元素
//如果要得到position位置上的元素,那么就应该访问position前面那个结点的link
public static IntNode listPosition(IntNode head, int position){
IntNode = point;
if(position <= 0)
throw new IllegalArgumentException("position is not positive!");
point = head;
for(int i=1; (i<position) && (point != null); i++){
point = point.link;
}
return point;
}
假如想要获取链表的长度,一个简单的方法是定义一个结点从头走到尾,累计它的长度
//获取链表的长度
public static int listLength(IntNode head){
IntNode point;
int length = 0;
//如果是一个空链表,返回长度0
//访问下个结点的方式除了point=point.link
//还有point=point.getLink();
for(point = head; point != null; point = point.link){
length;
}
return length;
}
有了这些基本方法,链表的操作差不多完成了。但是当我们想要产生一个已有链表的副本或者复制链表的一部分,要怎么办呢?
下面就展示了定义一个方法用来复制链表,通过访问链表的头部引用,然后逐个复制元素到新的链表;
public static IntNode listCopy(IntNode point){
IntNode copyHead;
IntNode copyTemp;
if(point == null)
return null;
copyHead = new IntNode(point.data, null);
copyTemp = copyHead;
while(point.link != null){
point = point.link;
copyTemp.addNodeAfter(point.data);
copyTemp = copyTemp.link;
}
return copyHead;
}
//下面是复制链表的简单应用
/*
IntNode list;
IntNode copy;
list = new IntNode(10, null);
list.addNodeAfter(20);
list.addNodeAfter(30);
copy = IntNode.listCopy(list);
*/
//下面是定义一个方法,给出链表要复制的起始位置和结束位置,并且两个位置不为空
//定义一个结点数组存储返回的副本的头尾引用
public static IntNode[] copyListPart(IntNode begin, IntNode end){
IntNode copyHead;
IntNode copyTail;
IntNode[] copyArray = new IntNode[2];
if(begin == null)
throw new IllegalArgumentException("起始位置不能为空!");
if(end == null)
throw new IllegalArgumentException("结束位置不能为空!");
//副本的头尾引用都指向原链表的头部引用,不断添加复制的元素同时copyTail向后移动直到end的位置
copyHead = new IntNode(begin.data, null);
copyTail = copyHead;
while(begin != end){
begin = begin.link;
if(begin == null)
throw new IllegalArgumentException("结束位置输入错误!");
copyTail.addNodeAfter(begin.data);
copyTail = copyTail.link;
}
copyArray[0] = copyHead;
copyArray[1] = copyTail;
return copyArray;
}