Java集合篇二:LinkList

package com.test.collection;

/**
 * 自定义实现LinkList
 * 
 * 1.双向链表
 * 实现原理:底层封装Node节点对象(每个节点存放有3部分内容:1.上个节点的位置,2.当前节点内容,3.下一个节点的位置)
 * 
 * 2.查询
 * LinkList 相较 ArrayList 查询效率低:
 * 由于LinkList底层存放元素的不是数组,不能直接通过索引进行获取,需要从头或者从尾逐一遍历索引节点对象。
 * ArrayList直接通过索引获取即可。
 * 
 * 3.删除、插入
 * linkList 相较ArrayList 插入、删除的效率高 
 * LinkList 直接打断前后的链接,链接到新对象即可;
 * 而ArrayList插入之后需要对后面的元素 进行整体移位
 * @author chenx
 *
 */
public class MyLinkList {
    private Node first;
    private Node last;
    public int size;
    
    public void add(Object obj){
        Node node=new Node();
        if(first == null){
            node.prev=null;
            node.element=obj;
            node.next=null;
            first=node;
            last=node;
        }else{
            //默认直接追加到最后
            node.prev=last;
            node.element=obj;
            node.next=null;
            last.next =node;
            last =node;
        }
        size ++;
    }
    
    /**
     * 由于不是数组,不能直接通过索引进行获取,需要从头或者从尾逐一遍历索引节点对象
     * 因此,相较ArrayList查询要慢
     * @param index
     * @return
     */
    public Object get(int index){
        rangeCheck(index);//下标越界检查
        Node temp=node(index);//获取当前节点
        return temp.element;
    }
    
    /**
     * 链表移除,直接打断前后的链接,链接到新对象即可;
     * 而ArrayList删除之后需要对后面的元素 进行整体移位,
     * 因此:linkList 相较ArrayList 删除的速度快
     * @param index
     * @param obj
     */
    public void remove(int index){
        rangeCheck(index);//下标越界检查
        Node temp=node(index);//获取当前节点
        Node up=temp.prev;
        Node down=temp.next;
        
        if(up==null){
            first = down;
        }else{
            up.next=down;
        }
        
        if(down==null){
            last = up;
        }else{
            down.prev=up;
        }
        
        size--;
    }
    //获取节点
    Node node(int index){//通过节点遍历实现类似索引的效果
        Node temp=first;
        if(first !=null){
            if(index <(size >>1)){
                temp=first;
                for(int i=0;i<index;i++){
                    temp = temp.next;
                }
            }else{
                temp=last;
                for(int i=size;i>index;i--){
                    temp = temp.prev;
                }
            }
        }
        return temp;
    }
    /**
     * 链表插入,直接打断前后的链接,链接到新对象即可;
     * 而ArrayList插入之后需要对后面的元素 进行整体移位,
     * 因此:linkList 相较ArrayList 插入的速度快
     * @param index
     * @param obj
     */
    public void add(int index,Object obj){
        Node temp=node(index);//获取当前节点
        Node newNode=new Node();
        newNode.element=obj;
        if(temp!=null){
            Node up=temp.prev;
            up.next=newNode;
            newNode.prev=up;
            newNode.next=temp;
            temp.prev=newNode;
            size++;
        }
    }
    
    public int size(){
        return size;
    }
    
    //下标越界检查
    private void rangeCheck(int index){
        if(index<0 || index>size){
            try {
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args){
        MyLinkList mylinkList=new MyLinkList();
        mylinkList.add("aaa");
        mylinkList.add("bbb");
        mylinkList.add("ccc");
        
        mylinkList.remove(1);
        for(int i=0;i<mylinkList.size;i++){
            System.out.println(mylinkList.get(i));
        }
    }
}

 Node.java

package com.test.collection;

public class Node {
    Node prev;
    Object element;
    Node next;
    public Node() {
    }
    public Node(Node prev, Object element, Node next) {
        super();
        this.prev = prev;
        this.element = element;
        this.next = next;
    }
}

 

posted @ 2016-12-28 22:51  陈小兵  阅读(459)  评论(0编辑  收藏  举报