Java数组和链表的区别

Java数组和链表的区别

从数据结构上说,数组的内存空间是连续的,我们创建数组的时候系统就会为我们开辟固定数目的内存空间,如果内存不足,就会创建失败,例如创建数组的两种方式:
int[] a=new int[3];
int[] b=new int[]{1,2,3};

可以看到我们创建数组的时候已经指定了数组的大小,且不能动态更改数组的大小,是因为创建时候已经分配了连续的固定内存空间,每个元素占用两个字节,这样我们就可以通过连续的内存,去访问数组的元素;

链表的内存分配是动态的,链表的元素占用的空间包含元素占用的空间,还有指向上一个或者下一个元素的指针(双链表,单链表);

这样我们可以得出各自的优缺点:

数组链表的优缺点:
数组占用空间小,链表元素还要包涵上一元素和下一个元素的的信息
数组的访问速度快,因为内存是连续的
数组内部元素可以随机访问,而链表依赖于上一个元素的信息

链表的插入删除操作由于数组,因为内存不连续,只需要更改元素的前后节点信息就行了,并不需要更改元素内存地址,而数组的连续内存想要插入和删除的话就要移动所有的内存地址
链表的内存利用率高于数组,链表内存是分散的一个元素占用一块空间,数组元素少于内存空间的话,会有部分的内存浪费;
链表的扩展性强,数组的创建完成内存大小就确定了,满了就没法扩展只能再次创建新的数组,而链表可以随意的增加扩展

效率:数组查询效率高,链表增,删效率高

下面是个单链表的实现:

public class LinkList<T> {      
      public class Node{  //定义节点         
           private T data;         
           private Node next;         
           public Node(){            
            }          
           public Node(T data,Node next){              
               this.data=data;              
               this.next=next;         
           }      
    }     
    private Node header;//头节点      
    private Node tail;//尾节点      
     private int size;//链表大小  
    //构造函数初始化数据     
    public LinkList(){         
        header=null;          
        tail=null;     
    }      
    public LinkList(T element){        
         header=new Node(element,null);         
         tail=header;         
          size++;    
   }     

//采用尾插法为链表添加新节点    
  private void add(T element) {        
      if(header==null){  
            header=new Node(element,null);  
            tail=header;  
        }else{  
            Node newNode=new Node(element,null);  
            tail.next=newNode;  
            tail=newNode;  
        }  
        size++;  
    }  

      //在index位置插入节点element  
    public void insert(T element,int index){  
        if(index<0||index>size){  
            throw new IndexOutOfBoundsException("线性表索引越界");  
        }  
        if(header==null){  
            add(element);  
        }else{  
            if(index==0){  
                addAtHeader(element);  
            }else{  
                Node prev=getNodeByIndex(index-1);  
                prev.next=new Node(element,prev.next);  
                size++;  
            }  
        }  
    }  

    //采用头插法为链表添加新节点  
    private void addAtHeader(T element){  
        header=new Node(element,header);  
        if(tail==null){  
            tail=header;  
        }  
        size++;  
    }  


    //返回指定位置index的节点      
    public T get(int index){        
            return getNodeByIndex(index).data;      
    }      
    private Node getNodeByIndex(int index) {          
           if(index<0||index>size-1){             
                 throw new IndexOutOfBoundsException("线性表索引越界");          
           }         
           Node current=header;         
           for(int i=0;i<size;i++,current=current.next){              
                 if(i==index){      
                         return current;             
                  }         
           }       
            return null;     
     }  
    //链表长度     
     public int length(){          
            return size;     
    }      
    //返回element在链表的位置,-1表示不存在    
    public int locate(T element){          
           Node current=header;         
           for(int i=0;i<size;i++,current=current.next){              
                  if(current.data==element){                 
                              return i;            
                  }          
           }         
          return -1;    
     }  

    //删除index位置的节点  
    public T delete(int index){  
        if(index<0||index>size-1){  
            throw new IndexOutOfBoundsException("线性表索引越界");  
        }  
        Node del=null;  
        if(index==0){  
            del=header;  
            header=header.next;  
        }else{  
            Node prev=getNodeByIndex(index-1);  
            del=prev.next;  
            prev.next=del.next;  
            del.next=null;  
        }  
        size--;  
        return del.data;  
    }  

    //从链表后面删除一个节点  
    public T remove(){  
        return delete(size-1);  
    }  

    //是否为空  
    public boolean empty(){  
        return size==0;  
    }  
    //清空链表  
    public void clear(){  
        header=null;  
        tail=null;  
        size=0;  
    }  

    public String toString(){  
        if(empty()){  
            return "[]";  
        }else{  
            StringBuilder sb=new StringBuilder("[");  
            for(Node current=header;current!=null;current=current.next){  
                sb.append(current.data.toString()+", ");  
            }  
            int len=sb.length();  
            return sb.delete(len-2, len).append("]").toString();  
        }  
    }  
    public static void main(String[] args) {         
          LinkList<String> list=new LinkList<String>();        
          list.insert("1", 0);          
          list.add("2");         
          list.add("3");         
          System.out.println(list.toString());          
          list.insert("4", 1);         
          System.out.println(list.toString());       
           list.delete(2);         
           System.out.println(list.toString());         
           System.out.println("1在链表中的位置:"+list.locate("1"));         
           System.out.println("链表中索引2处的元素:"+list.get(2));     
    }  
 }  
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值