java:数据结构

一,命名规范定义

       1,java.util.collection接口来定义数据结构中方法的命名规范。

  2,java.util.List此接口是collection的子接口,要求实现此接口的类,必须满足数据是有序且可以重复的特性。

  3,java.util.Set此接口是collection的子接口,要求实现此接口的类,必须满足数据是无序且不可重复的特性。

二,数据结构的实现类

  List

    1,java.util.ArrayList以可变数组长度的方式实现java.util.List接口。

例:

package myutil;
/*总结: ArrayList适合查找元素,而不适合 删除、插入元素*/
public class ArrayList {
       Object[] elementData;
       int size;

         public ArrayList(){
             this(10);
         }

         public ArrayList(int initialCapacity){
             if (initialCapacity < 0)
                 throw new IllegalArgumentException("Illegal Capacity: "+
                         initialCapacity);
             this.elementData = new Object[initialCapacity];
         }
         public boolean add(Object obj){
                this.ensureCapacity(this.size+1);
               this.elementData[size++] = obj;
               return true;
         }



    /* 由于在数组中删除元素需要调整数组的下标,例如在100个元素中删除第一个元素需要调下标99次,
       因此在ArrayList中删除元素的效率很低(特别是删除在数组中靠前的元素)*/
         public Object remove(int index){

                Object oldEle=this.elementData[index];
                for(int i=index;i<size;i++){
                      this.elementData[i]=this.elementData[i+1];
                }
                size--;

             return oldEle;

         }
       /* 由于可变长度实际上是新数组和原数组之间一个copy,因此效率很低,在创建ArrayList的时候应该尽量使用
          第二种构造函数。*/
         private void ensureCapacity(int capacity){
                if(capacity>this.elementData.length){
                        Object[] newElementData = new Object[this.elementData.length*3/2];//扩展到1.5倍。
                        this.copy(newElementData);
                }
         }
         private void copy(Object[] newElementData){
                   for(int i=0;i<size;i++){
                               newElementData[i]=this.elementData[i];
                   }
                   this.elementData=newElementData;
         }


         public Object get(int index){
             return this.elementData[index];
         }
         public int size(){
             return this.size;
         }

}

    2,java.uti.LinkedList以链表的方式实现java.util.List接口。

例:

package myutil;

import java.util.Collection;
import java.util.Iterator;

/*总结:由于LikedList由链表实现(对象的引用),因此在删除链表头或尾部元素的时候效率非常高,这刚好与ArrayList相反
  LinkedList的遍历应该按照java.util.Iterator(迭代器规)规范实现遍历,这种方式是从链表表的头部往next或previous顺序返回数据,
  效率与ArrayList相同,因此如果要遍历LinkedList应该使用迭代器而不是get方法。
*
* */
public class LinkedList implements Iterable  {
       Node header = new Node(null);
       int size;

      public LinkedList(){
          this.header.previous = header.next = header;
       }

      public Iterator  iterator(){
            class IteratorImp implements Iterator{
                Node ele=header;
                @Override
                public boolean hasNext() {
                    return ele.next!=header;
                }

                @Override
                public Object next() {
                      Node n=ele.next;
                        ele=n;
                    return n.ele ;
                }
                @Override
                public void remove() {

                }
            }

          return new IteratorImp();
      }

      public boolean add(Object ele){
            Node newNode = new Node(ele);
            newNode.previous = header.previous;
            newNode.next = header;
            header.previous.next = newNode;
            header.previous = newNode;
            size++;
           return true;
       }

     private Node node =header;
     public boolean add2(Object ele){
         Node newNode = new Node(ele);
           header.previous = newNode;
           node.next = newNode;

          newNode.previous = node;
          newNode.next = header;

          node = newNode;
           size++;
        return true;

    }
    public void removeFirst(){
           Node removeEle=header.next;

               removeEle.next.previous = header;
                 header.next = removeEle.next;

            removeEle = removeEle.previous = removeEle.next =  null;
              size--;
    }

    public void removeLast(){


    }

       //查找元素时效率低,需要对链表进行遍历。ArrayList效率高因为数组可以快速定位到指定下标的元素。

     public Object get(int index){
                if(index  < size>>1){
                    Node node=header;
                       for(int i=0;i<=index;i++){
                           node=node.next;
                       }
                       return node.ele;
                }else{

                    Node node=header;
                    for(int i=size;i>index;i--) {
                        node = node.previous;
                    }
                    return node.ele;
                }
     }
     public int size(){
           return this.size;
       }





    class Node{
         Node next;
         Node previous;
         Object ele;

         Node(Object ele){
              this.ele =ele;
         }

    }
}

 

  Set

    1,java.util.HashSet    HashSet由HashMap实现,把所有元素都储存在HashMap的key中。(此实现依照HashMap方法实现)

  Map

        (map是key-value的数据储存关系,与集合接口没有任何关联)

      1,常用实现类java.util.HashMap

例:

package myutil;

import java.util.Iterator;
@SuppressWarnings("all")
public class HashMap{
    static final int DEFAULT_INITIAL_CAPACITY = 16;
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
    Node[] elementsData;
    public int threshold;
    int size;


    public HashMap(int initialCapacity, float loadFactor) {
        this.threshold= (int)(initialCapacity*loadFactor);
    }
    public HashMap(){
        this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
        this.elementsData = new Node[8];
        init();

    }

    public Object get(Object key){
        int index= indexFor(key.hashCode());
          Node ele=this.elementsData[index];
            for(; ele!=null;ele=ele.next){
                if(ele.key==key)
                    return ele.value;
            }
        return null;
    }

    public Object put(Object key, Object value){
          if(size+1>threshold){
                //reHash 扩展Hash表的长度。
          }
        return addNode(key,value);

    }
    public void init(){

    }
    public Node addNode(Object key, Object value){
        Node ele=new Node(key,value);
        int index= indexFor(key.hashCode());
        ele.next = this.elementsData[index];
        this.elementsData[index]=ele;
        size++;
        return ele;
    }

    public  int indexFor(int h) {
        int index=h & (this.elementsData.length-1);
        if(index<0)
             index=index*-1;

          return index;
    }

    public static class Node{
        Object key;
        Object value;
        Node next;

          public Node(Object key,Object value){
              this.key = key;
              this.value =  value;
          }
          public Node(){


          }

    }

}

      

           2,java.util.LinkedHashMap如果需要使用HashMap的功能又需要对储存的数据进行排序则使用LinkedHashMap。

例:

package myutil;
import java.util.Iterator;
public class LinkedHashMap extends HashMap implements Iterable {
      Node header;
    @Override
    public void init(){
         header=new Node(null,null);
         header.previous = header.next = header;
    }
    @Override
    public Iterator iterator() {
        class IteratorImp implements Iterator{
            Node ele=header;
            @Override
            public boolean hasNext() {
                return ele.next!=header;
            }
            @Override
            public Object next() {
                Node n=ele.next;
                ele=n;
                return n.value ;
            }
            @Override
            public void remove() {

            }
        }
        return new IteratorImp();
    }
    class Node extends HashMap.Node{
        Node previous;
        Node next;
        public Node(Object key,Object value){
            super(key,value);
        }
        public boolean addBefore(){
            this.previous = header.previous;
            this.next = header;
            header.previous.next = this;
            header.previous = this;
            return true;
        }

    }



   /* 重写addNode方法。由于HashMap在调用put方法时会调用addNode方法。因此重写此方法后
    LinkedHashMap在调用put方法时会执行重写的addNode,从而将存储元素存储到Hash表的同时,
    在添加到双向链表的结构中去。*/
   @Override
    public Node addNode(Object key, Object value){
         super.addNode(key,value);
          Node e = new Node( key, value);
            e.addBefore();
        return e;
    }
}

 

   

posted @ 2017-12-12 20:23  dybe  阅读(237)  评论(0编辑  收藏  举报