链表的简单学习

链表

最近看了《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;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值