java_linear list

1.线性表的顺序存储结构,类似ArrayList

package collectionsFramework.linearlist;

import java.util.Arrays;

/** 
 * @Package collectionsFramework.linearlist

 * @ClassName: Singlylinkedlist

 * @Description: TODO(arrayList的增删改查)

 * @author andy

 * @date 2013-11-21 下午05:39:53

 */
public class SinglyLinkedList<T>{
    private Object[] elementData;
    private int size;
    private int capacity;
    private int defaultCapacity = 10;
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
    public SinglyLinkedList(){
        capacity =  defaultCapacity;
        elementData = new Object[capacity];
    }
    
    public int getSize() {
        return size;
    }
    
    public boolean  isEmpty(){
        return size == 0;
    }
    
    //在线性顺序表的开始处添加一个元素。
    public void add(T element){
        insert(element , size); 
    }
    //在指定位置处添加一个元素
    private void insert(T element, int index) {
       if(index < 0 || index > size){
           throw new IndexOutOfBoundsException("数组下标越界!");
       }
       ensureCapacity(index+1);
       System.arraycopy(elementData, index, elementData, index+1, size-index);
       elementData[index] = element;  
       size++;
    }
    
    private void ensureCapacity(int size) {
        if(size > capacity){
            //容量增大两倍,即为原来的3倍
            capacity = capacity + capacity<<1;
            //如果其值比最大值还大
            capacity = capacity >Integer.MAX_VALUE ? hugeCapacity(size):capacity;
            
            elementData = Arrays.copyOf(elementData, capacity);
        }
    }
    
    //如果值比MAX_ARRAY_SIZE还大,那么其返回值就是Integer.MAX_VALUE,否则就是MAX_ARRAY_SIZE
    private static int hugeCapacity(int minCapacity) {
        return minCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    }
    
    //删除顺序线性表中指定索引处的元素 
     public T remove(int index){
         if(index < 0 || index > size-1){
             throw new IndexOutOfBoundsException("所要删除元素的索引越界");
         }
         T oldData = (T)elementData[index];
         System.arraycopy(elementData, index+1, elementData, index, size-(index+1));
         elementData[size-1] = null;
         size--;
         return oldData;
     }
     
    //获取顺序线性表中索引为i处的元素
     public T get(int i)  {
         if (i < 0 || i > size - 1){
             throw new IndexOutOfBoundsException("数组下标越界!");  
         }
         return (T)elementData[i];
     }
     
     public String toString()  
        {  
            if (size == 0)  
            {  
                return "[]";  
            }  
            else  
            {  
                StringBuilder sb = new StringBuilder("[");  
                for (int i = 0 ; i < size ; i++ )  
                {  
                    sb.append(elementData[i].toString() + ", ");  
                }  
                int len = sb.length();  
                return sb.delete(len - 2 , len).append("]").toString();  
            }  
     }  

    public static void main(String[] args) {
        SinglyLinkedList<String> list = new SinglyLinkedList<String>();
        System.out.println(list);
        list.add("a");
        System.out.println(list);
        list.add("b");
        System.out.println(list);
        list.add("c");
        System.out.println(list);
        list.add("d");
        System.out.println(list);
        list.add("e");
        System.out.println(list);
        list.remove(2);
        System.out.println("remove之后:" + list);
        System.out.println(list.get(2));
    }
}
View Code

 2.线性表的链式实现,是一个双向链表,类似LinkedList

package collectionsFramework.linearlist;


/**
 * @Package collectionsFramework.linkedlist
 * 
 * @ClassName: DoublyLinkedList
 * 
 * @Description: TODO(LinkedList的增删改查)
 * 
 * @author andy
 * 
 * @date 2013-11-21 下午05:40:31
 */
public class DoublyLinkedList<T> {
    private class Node<T> {
        private T data;
        private Node<T> prev;
        private Node<T> next;

        public Node() {

        }

        public Node(T data, Node<T> prev, Node<T> next) {
            this.data = data;
            this.prev = prev;
            this.next = next;
        }
    }

    private Node<T> header;
    private Node<T> tail;
    private int size;

    public DoublyLinkedList() {
        header = null;
        tail = null;
    }

    // 返回链表的长度
    public int length() {
        return size;
    }

    public boolean empty() {
        return size == 0;
    }

    //在链表尾部添加新节点
    public T add(T element) {
        if (empty()) {
            header = new Node<T>(element, null, null);
            tail = header;
        } else{
            Node<T> newNode = new Node<T>(element , tail, null);  
            tail.next = newNode;
            tail = newNode;
        }
        size++;
        return element;
    }
    
    //在链表头部添加新节点
    public T addFirst(T element) {
        header = new Node<T>(element, null, header);
        if(empty()){
            tail = header;
        }
        size++;
        return element;
    }

    public T addLast(T element) {
        return add(element);
    }

    //指定位置出插入元素
    public T add(int index, T element) {
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("线性表索引越界");
        }
        // 如果还是空链表
        if (empty()) {
            add(element);
        } else {
            if(index == 0){
                addFirst(element);
            }else{
                //插入点的前一个结点
                Node<T> prev = getNudeByIndex(index-1);
                //a、b、c、d
                //在c这是插入一个e结点,并且它的prev指向上面的b,它的next指向d,但是b的next引用和d的prev引用还是没有变
                Node<T> newNode = new Node<T>(element, prev, prev.next);
                //b的next引用指向e
                prev.next = newNode;
                //d的prev引用指向e
                prev.next.prev = newNode;
                size++;
            }
        }
        
        return element;
    }
    
    //根据索引index获取指定位置的节点,二分法查找元素
    public Node<T> getNudeByIndex(int index){
        if (index < 0 || index > size) {
            throw new IndexOutOfBoundsException("线性表索引越界");
        }
        
        if(empty()){
            return null;
        }
        
        if(index <= size/2){
            int i=0;
            for(Node<T> currentNode = header; i <= size/2 && currentNode!=null; i++,currentNode=currentNode.next){
                if(i == index){
                    return currentNode;
                }
            }
        }else{
            int i=size-1;
            for(Node<T> currentNode = tail; i > size/2 && currentNode!=null; i--,currentNode=currentNode.prev){
                if(i == index){
                    return currentNode;
                }
            }
        }
        return null;
    }
    
    //获取但不移除此列表的头(第一个元素)。
    public T element() {
        return getFirst();
    }

    //获得指定索引出的数据
    public T get(int index) {
        if (index < 0 || index > size - 1) {
            throw new IndexOutOfBoundsException("线性表索引越界");
        }
        
        return getNudeByIndex(index).data;
    }

    public T getFirst() {
        return header == null? null:header.data;
    }

    public T getLast() {
        return tail == null? null:tail.data;
    }

    public T offer(T element) {
        return add(element);
    }

    public T offerFirst(T element) {
        return addFirst(element);
    }

    public T offerLast(T element) {
        return addLast(element);
    }

    public T peek() {
        return getFirst();
    }

    public T peekFirst() {
        return getFirst();
    }

    public T peekLast() {
        return getLast();
    }

    public T poll() {
        return removeFirst();
    }

    public T pollFirst() {
        return removeFirst();
    }

    public T pollLast() {
        return removeLast();
    }

    public T pop() {
        return removeFirst();
    }

    public T push(T element) {
        return addFirst(element);
    }

    public T remove() {
        return remove(0);
    }

    public T remove(int index) {
        if(index < 0 || index > size -1){
            throw new IndexOutOfBoundsException("线性表索引越界");
        }
        
        if(empty()){
            return null;
        }
        Node<T> delNode;
        if(index == 0){
            //a、b、c、d、e 移除a结点,下面得到a结点
            delNode = header;
            //将b结点设置为头结点
            header = delNode.next;
            //并将b结点对上一个a节点的引用设置为空
            delNode.next.prev = null;
            //并将a结点对下一个b结点的引用设置为空
            delNode.next = null;
            //将删除结点设置为空
            //delNode.data = null;
            //delNode = null;
            size--;
            return delNode.data;
        }else if(index == (size-1)){
            //a、b、c、d、e 移除e结点,下面得到e结点
            delNode = tail;
            //得到d结点,并将d结点的下一点指向null
            delNode.prev.next = null;
            //并将e结点对上一个节点的引用设置为null
            delNode.prev = null;
            //将删除结点设置为空
            //delNode.data = null;
            //delNode = null;
            size--;
            return delNode.data;
            
        }else{
            //a、b、c、d、e 移除c结点,下面得到c结点
            delNode = getNudeByIndex(index);
            //得到b结点,并将b结点的下一点指向d结点
             delNode.prev.next = delNode.next;
            //并将d结点对上一个节点的引用设置为b
            delNode.next.prev = delNode.prev;
            //并将c结点对b、d的引用设置为空
            delNode.next = null;
            delNode.prev = null;
            size--;
            return delNode.data;
        }
    }

    public T removeFirst() {
        return remove(0);
    }

    public T removeLast() {
        return remove(size-1);
    }

    public void clear() {
        if(empty()){
            return;
        }
        for (Node<T> node = header; node != null; node = node.next) {
            node.data = null;
            node.prev = null;
            node.next = null;
        }
        header = null;
        tail = null;
        size = 0;
    }
    
    public String toString()  
    {  
        //链表为空链表时  
        if (empty())  
        {  
            return "[]";  
        }  
        else  
        {  
            StringBuilder sb = new StringBuilder("[");  
            for (Node<T> 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) {
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<String>();
        System.out.println(linkedList);
        linkedList.add("a");
        linkedList.add("b");
        linkedList.add("c");
        linkedList.add("d");
        System.out.println(linkedList);
        System.out.println("移除对象:" + linkedList.removeFirst());
        System.out.println(linkedList);
        System.out.println("移除对象:" + linkedList.remove(2));
        System.out.println(linkedList);
    }
}
View Code
原文地址:https://www.cnblogs.com/o-andy-o/p/3442470.html