LinkedList双链表简单分析,及单链表的实现代码

最近闲来无事,看了一下LinkedList源码,自己也动手尝试写了下单链表、双链表的代码。话说,动手才是检验真理的唯一途径。
先来看看java内部实现的LinkedList源码。后面OneWayLinkedList是自己实现的单链表。

双向链表通过Header节点暴露出去,通过他来进行查询其他的节点信息。
      private transient Entry<E> header = new Entry<E>(null, null, null);
    private transient int size = 0;

    /**
     * Constructs an empty list.
     */
    public LinkedList() {
        header.next = header.previous = header;
    }
    每一个节点都保存了当前节点的上一个节点、下一个节点索引 ,所以增加、移除元素起来非常方便、高效。
    ArrayList 增加、删除元素需要动态的维护数组,效率较低public boolean add(E e) {
addBefore(e, header);
        return true;
    }
   private Entry<E> addBefore(E e, Entry<E> entry) {
Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
size++;
modCount++;
return newEntry;
    }

   private E remove(Entry<E> e) {
if (e == header)
    throw new NoSuchElementException();

        E result = e.element;
e.previous.next = e.next;
e.next.previous = e.previous;
        e.next = e.previous = null;
        e.element = null;
size--;
modCount++;
        return result;
    }

    LinkedList查询起来比较麻烦,需要从索引开始遍历查找。ArrayList的主要是基于数组来实现,在查询基于数组下标直接就可获取元素。
    查询元素见如下代码 
       public E get(int index) {
        return entry(index).element;
    }
  private Entry<E> entry(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("Index: "+index+
                                                ", Size: "+size);
        Entry<E> e = header;
        if (index < (size >> 1)) {
            for (int i = 0; i <= index; i++)
                e = e.next;
        } else {
            for (int i = size; i > index; i--)
                e = e.previous;
        }
        return e;
    }
单链表相比较来说,要简单些。

根据LinkedList,仿照写的单链表实现类,如下为单链表的实现代码

package test;

/**
*
* @Title: OneWayLinkedList.java
* @Package test
* @Description: 单向链表 操作
* @author lisq
* @date 2016年1月8日 上午10:42:00
* @version V1.0
*/
public class OneWayLinkedList {

/* 头节点 */
private Node<T> header;

/* 当前链表的节点数 */
private int size;

public int size() {
    return size;
}

public OneWayLinkedList() {
    header = new Node<T>(null, null);
}


/* 添加节点 */
public void add(T e) {
    Node<T> newNode = new Node<T>(e,null);
    // 第一个节点
    if (size == 0) {
        header.next = newNode;
    } else {
        Node<T> nextNode = header.next;
        do {
            // 查找最后一个节点,因为最后一个节点的下一个节点为null
            if (nextNode.next == null) {
                // 新加入的节点放到最后
                nextNode.next = newNode;
                break;
            }
            nextNode = nextNode.next;
        } while (true);
    }
    size++;
}

/* 添加节点 */
public void add(T e , int index) {
    Node<T> node = entry(index);
    node.element = e;
}


/* 删除节点 */
public boolean removeObject(T e) {
    // 默认从第一个节点开始查找
    Node<T> node = header.next;
    // 上一个节点 ,默认为头节点
    Node<T> prev = header;
    if (node == null) {
        System.out.println("无节点数据,无法删除!");
        return false;
    }
    do {
        boolean flag = false;
        /* 校验空元素null */
        if (e == null) {
            if (node.element == null) {
                flag = true;
            }
        } else {
            if (e.equals(node.element)) {
                flag = true;
            }
        }
        /*
         * 1,找到对应的节点元素后,把当前节点的上一个节点指向当前节点的下一个节点 2,把当前节点置为null
         * (node.prev).next = (node.next)
         */
        if (flag) {
            //把上一个节点的下一个节点指向为当前节点的下一个节点
            prev.next = node.next;
            //删除当前节点信息
            node.next = null;
            node.element = null;
            size--;
            return true;
        }
        // 判断是否为最后一个节点,因为最后一个节点的下一个节点为null
        if (node.next == null) {
            System.out.println("没有找到相应的节点");
            return false;
        }
        prev = node;
        node = node.next;
    } while (true);
}

/* 删除节点 */
public boolean removeIndex(int index) {
    T e = get(index);
    return removeObject(e);
}

/* 通过下表查找元素 */
public T get(int index) {
    return entry(index).element;
}

private Node<T> entry(int index) {
    if (index < 0 || index >= size) {
        throw new IndexOutOfBoundsException("下标越界");
    }
    Node<T> node = null;
    for (int i = 0; i < size; i++) {
        node = (i == 0) ? header.next : node.next;
        if (i == index) {
            break;
        }
    }
    return node;
}

/*数组转换*/
public Object[] toArray() {
    Object[] obj = new Object[size];
    int index = 0;
    for (Node<T> node = header.next; node != null; node = node.next) {
        obj[index++] = node.element;
    }
    return obj;
}

}

/单链表/
class Node {

// 节点元素
public T element;

// 下一个节点
public Node<T> next;

public Node(T e, Node<T> entry) {
    this.element = e;
    this.next = entry;
}

}
“`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值