动手实现LinkedList

对于链表,我们是再熟悉不过了。下面我们来简单实现一下。

链表是由1个或多个节点连接形成的,所以我们从节点出发,定义节点如下

class Lnode<T>{
    public T data;
    public Lnode<T> next;

    public Lnode(T key){
        data = key;
        next = null;
    }
}

一个泛型表示节点中的值,next指向下一个节点。

接下来定义链表类,链表定义不是很难。

private Lnode<T> first,last;

private int length;

private Iterator<T> iterator;

表头,表尾和长度以及一个迭代器。

构造方法也很简单,只需让表头表尾置null,length置0,将迭代器初始化

public MyLinked(){
    first = last = null;
    length = 0;
    iterator = new LinkedIterator();
}

下面就是操作链表的各种方法,首先看最简单的size方法。直接返回成员属性length就行。

//求长度
public int size(){
    return length;
}

下来是获取节点的值,获取节点可以单独写一个方法,方便在之后的set、remove方法使用

//获取第i个节点
private Lnode<T> getNode(int i){
    if (i<0 || i>=length)
        return null;
    if (i==0)
        return first;
    Lnode<T> p = first;
    int j=0;
    while (p!=null && j<i){
        p = p.next;
        j++;
    }
    return p;
}

    获取节点的值方法只需得到节点,对接点进行判空,不为空返回节点值

//获取第i个节点的值
public T get(int i){
    Lnode<T> p = getNode(i);
    if (p==null)
        return null;
    else
        return p.data;
}

    接下来是修改某个节点的值,过程和获取节点的值类似,不过将返回节点的值改为赋值即可。

//修改i号节点的值
public boolean set(int i,T x){
    Lnode<T> p = getNode(i);
    if (p==null)
        return false;
    else {
        p.data = x;
        return true;
    }
}

    add方法很常用,而且add方法也有好几种,我们可以使用方法重载进行编写,添加节点时,注意添加到表头,表中间和表尾。

//添加节点
public void add(int i,T x){
    int j = i-1;
    Lnode<T> p;
    Lnode<T> s = new Lnode<>(x);
    if (first==null || length == 0){
        first =s;
        last = s;
    }else if(j<0) {
        s.next = first;
        first = s;
    }else if (j>=length-1){
        last.next = s;
        last = s;
    }else {
        p = getNode(j);
        s.next = p.next;
        p.next = s;
    }
    length++;
}
    可以根据上面这个方法对add方法进行各种各样的重载。

//添加至末尾
public void add(T x){
    add(length,x);
}
//添加至表头
public void addFirst(T x){
    add(0,x);
}
//添加至表尾
public void addLast(T x){
    add(length,x);
}

    接下来是节点删除方法,和add方法类似,注意删的是表头还是表中间

public Lnode<T> removeNode(int i){
    Lnode<T> p,q;
    if (first==null)
        return null;
    if (i==0){
        p = first;
        first = first.next;
        length--;
        return p;
    }
    if (i>=1 && i<=length-1){
        p = getNode(i-1);
        q = p.next;
        p.next = q.next;
        if (q==last)
            last = p;
        length--;
        return p;
    }
    return null;
}
    根据上面这个节点删除方法,可以进行各种各样的重载。

//删除表头
public T removeFirst(){
    return removeNode(0).data;
}
//删除表尾
public T removeLast(){
    return removeNode(length-1).data;
}
//删除节点
public T remove(){
    return removeNode(0).data;
}
//删除特定的值
public T remove(T x){
    int i = indexOf(x);
    if (i<0)
        return null;
    else {
        return removeNode(i).data;
    }
}
//删除i号节点
public T remove(int i){
    Lnode<T> p = removeNode(i);
    if (p==null)
        return null;
    else
        return p.data;
}
    最后是值查找方法,遍历链表,如果找到相应的节点,返回,否则返回null。

//查找算法
public int indexOf(T key){
    Lnode<T> p = getNode(0);
    int j = 0;
    while (p!=null && j<length){
        if (p.data.equals(key))
            return j;
        p = p.next;
        j++;
    }
    return -1;
}

    实现迭代器也不难,和ArrayList不同,除了需要判断索引是否超过长度,还要判断当前节点是否为空。

private class LinkedIterator implements Iterator<T>{
    private int index = 0;
    private Lnode<T> current = first;

    @Override
    public boolean hasNext() {
        //在调用next后,index自增,确保index不等于链表的长度
        return (index!=length && current!=null);
    }

    @Override
    public T next() {
        T t = current.data;
        current = current.next;
        index++;
        return t;
    }
}

    在最后,源代码附上。

import java.util.Iterator;

public class MyLinked<T> implements Iterable<T>{

    class Lnode<T>{
        public T data;
        public Lnode<T> next;

        public Lnode(T key){
            data = key;
            next = null;
        }
    }

    private Lnode<T> first,last;

    private int length;

    private Iterator<T> iterator;

    public MyLinked(){
        first = last = null;
        length = 0;
        iterator = new LinkedIterator();
    }

    //求长度
    public int size(){
        return length;
    }

    //获取第i个节点
    private Lnode<T> getNode(int i){
        if (i<0 || i>=length)
            return null;
        if (i==0)
            return first;
        Lnode<T> p = first;
        int j=0;
        while (p!=null && j<i){
            p = p.next;
            j++;
        }
        return p;
    }

    //获取第i个节点的值
    public T get(int i){
        Lnode<T> p = getNode(i);
        if (p==null)
            return null;
        else
            return p.data;
    }

    //修改i号节点的值
    public boolean set(int i,T x){
        Lnode<T> p = getNode(i);
        if (p==null)
            return false;
        else {
            p.data = x;
            return true;
        }
    }

    //添加节点
    public void add(int i,T x){
        int j = i-1;
        Lnode<T> p;
        Lnode<T> s = new Lnode<>(x);
        if (first==null || length == 0){
            first =s;
            last = s;
        }else if(j<0) {
            s.next = first;
            first = s;
        }else if (j>=length-1){
            last.next = s;
            last = s;
        }else {
            p = getNode(j);
            s.next = p.next;
            p.next = s;
        }
        length++;
    }

    //添加至末尾
    public void add(T x){
        add(length,x);
    }
    //添加至表头
    public void addFirst(T x){
        add(0,x);
    }
    //添加至表尾
    public void addLast(T x){
        add(length,x);
    }

    //删除i号节点
    public T remove(int i){
        Lnode<T> p = removeNode(i);
        if (p==null)
            return null;
        else
            return p.data;
    }

    public Lnode<T> removeNode(int i){
        Lnode<T> p,q;
        if (first==null)
            return null;
        if (i==0){
            p = first;
            first = first.next;
            length--;
            return p;
        }
        if (i>=1 && i<=length-1){
            p = getNode(i-1);
            q = p.next;
            p.next = q.next;
            if (q==last)
                last = p;
            length--;
            return p;
        }
        return null;
    }
    //删除表头
    public T removeFirst(){
        return removeNode(0).data;
    }
    //删除表尾
    public T removeLast(){
        return removeNode(length-1).data;
    }
    //删除节点
    public T remove(){
        return removeNode(0).data;
    }
    //删除特定的值
    public T remove(T x){
        int i = indexOf(x);
        if (i<0)
            return null;
        else {
            return removeNode(i).data;
        }
    }
    //查找算法
    public int indexOf(T key){
        Lnode<T> p = getNode(0);
        int j = 0;
        while (p!=null && j<length){
            if (p.data.equals(key))
                return j;
            p = p.next;
            j++;
        }
        return -1;
    }

    private class LinkedIterator implements Iterator<T>{
        private int index = 0;
        private Lnode<T> current = first;

        @Override
        public boolean hasNext() {
            //在调用next后,index自增,确保index不等于链表的长度
            return (index!=length && current!=null);
        }

        @Override
        public T next() {
            T t = current.data;
            current = current.next;
            index++;
            return t;
        }
    }
    @Override
    public Iterator<T> iterator() {
        return new LinkedIterator();
    }
}

猜你喜欢

转载自blog.csdn.net/yanghan1222/article/details/80178192
今日推荐