实现LinkedList

 

实现链表

package com.lt.datastructure.LinkedList;

public class LinkedList<E> {
    //虚拟头结点
    private Node dummyhead;
    private int size;
    
    public class Node{
        public E e;
        public Node next;
        public Node(E e,Node next){
            this.e = e;
            this.next = next;
        }
        public Node(E e){
            this(e,null);
        }
        public Node(){
            this(null,null);
        }
        @Override
        public String toString() {
            return e.toString();
        }
    }
    
    public LinkedList(){
        dummyhead = new Node(null,null);
        size = 0;
    }

    //    返回元素个数
    public int getSize(){
        return size;
    }
    
    //    返回链表是否为空
    public boolean isEmpty(){
        return size == 0;
    }

    //    链表添加元素
    public void add(int index,E e){
        if(index<0 || index >size)
            throw new IllegalArgumentException("Add failed");
    
            //index的前一个位置
            Node prev = dummyhead;//dymmyhead.next 则 for(; i<index-1;)
            for(int i=0;i<index;i++){
                prev = prev.next;
            }
//                Node node = new Node(e);
//                node.next = prev.next;
//                //前一个元素指向node
//                prev.next =  node;
                prev.next = new Node(e,prev.next);
                size++;
            
            
    }
    
    //    在链表头添加元素
    public void addFirst(E e){
    //    Node node = new Node(e);
    //    //指向原来的第一个元素
    //    node.next = head;
    //    //head指向第一个元素
    //    head = node;
    //    head = new Node(e,head);
        add(0, e);
    }
    
    //    链表末尾添加元素
    public void addLast(E e){
        add(size,e);
    }
    
    //获取链表的第index个元素
    public E get(int index){
        if(index<0||index>=size){
            throw new IllegalArgumentException("Get failes.Illegal index");
        }
        //目的是从第一个开始
        Node cur = dummyhead.next;
        for(int i =0; i<index ; i++){
            //遍历index次,从指向1到指向index
            cur = cur.next;
        }
        return cur.e;
    }
    
    //获取第一个元素
    public E getFirst(){
        return get(0);
    }
    
    //获取最后一个元素
    public E getLast(){
        return get(size);
    }
  
    //修改链表的第index(0-size)个元素为e
    public void set(int index , E e){
        if(index<0 || index>size ){
            throw new IllegalArgumentException("Set failed. Illeagal index");
        }
        //目的是找到index位置的元素
        Node cur = dummyhead.next;
        for(int i=0; i<index ; i++){
            cur = cur.next;
        }
        cur.e = e;
    }
    
    //查询链表中是否有元素e
    public boolean contains(E e){
        Node cur = dummyhead.next;
        while(cur!=null){
            if(cur.e.equals(e)){
                return true;
            }
            cur = cur.next;
        }
        return false;
    }
    
    
    //在链表中删除指定位置的元素
    //找到待删除结点的前一个结点,使其next指向delNode.next,而delNode.next指向Null
    public E remove(int index){
        if(index<0 || index>=size ){
            throw new IllegalArgumentException("remove failed. Illeagal index");
        }
        //找到前一个结点,使其指向删除结点的后一个结点
        Node prev = dummyhead;
        for(int i=0;i< index ; i++){
            prev = prev.next;
        }
        //找到删除结点
        Node retNode = prev.next;
        prev.next = retNode.next;
        retNode.next = null;
        size--;
        return retNode.e;
    }
    
    //删除第一个元素
    public E removeFirst(){
        return remove(0);
    }
    
    //删除最后一个元素
    public E removeLast(){
        return remove(size-1);
    }
    
    //toString
    @Override
    public String toString() {
        
        StringBuilder res = new StringBuilder();
    
//        Node cur = dummyhead.next;
//        while(cur!=null){
//         res.append(cur+"->");
//         cur = cur.next;
//        }    
        
        for(Node cur= dummyhead.next; cur!=null; cur=cur.next){
            res.append(cur+"->");
        }
        res.append("null");
        
        return res.toString();
    }
    
}

测试:

package com.lt.datastructure.LinkedList;

public class Main {

    public static void main(String[] args) {
       LinkedList<Integer> linkedList = new LinkedList<>();
       for(int i=0 ; i<5 ; i++){
           linkedList.addFirst(i);
           System.out.println(linkedList);
       }
       linkedList.add(2, 666);
       System.out.println(linkedList);
    
       linkedList.remove(2);
       System.out.println(linkedList);
//       
       linkedList.removeFirst();
       System.out.println(linkedList);
//       
       linkedList.removeLast();
       System.out.println(linkedList);
    }       
    
    
}

测试结果:

复杂度分析:

  • 增  :需要遍历找到找到前一个位置   O(n/2)   O(n)
  • 删  :需要遍历,平均为O(n/2)  O(n)
  • 改   : 需要遍历,平均为O(n/2)  O(n)
  • 查  :需要遍历,平均为O(n/2)  O(n)

 

和数组对比:

  • 数组有索引的时候,可以快速访问
  • 如果只对链表头进行操作,和数组的时间复杂度差不多:O(1)
  • 链表是动态的,不会浪费内存空间

 

posted @ 2018-11-19 22:53  IslandZzzz  阅读(169)  评论(0编辑  收藏  举报