手写ArrayList、LinkedList

 ArrayList

package com.hjp.labs;

import org.omg.CORBA.PRIVATE_MEMBER;

/*
一、ArrayList的底层是Object类的数组,默认长度是10,超过10后,长度变为原长度的2倍+1。

二、可以简单的认为是一个动态数组;实际上ArrayList就是用数组实现的,长度不够时,调用Arrays.copyOf方法,拷贝当前数组到一个新的长度更大的数组。

三、特点:随机访问速度快,插入和移除性能较差(数组的特点);

    支持null元素;

    有顺序;

    元素可以重复;

    线程不安全。
    参考:http://blog.csdn.net/smile_juan/article/details/7272841

*/
public class MyArrayList<T> {

    private static final int DEFAULT_CAPACITY = 10;
    private int size;
    private T[] items;

    public int size() {
        return size;
    }

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

    public void ensureCapacity(int newCapacity) {

        if (newCapacity < size()) {
            return;
        }

        T[] oldItems = items;
        items = (T[]) new Object[newCapacity];

        for (int i = 0; i < size(); i++) {
            items[i] = oldItems[i];
        }
    }

    public MyArrayList() {
        clear();
    }

    public void clear() {
        size = 0;
        ensureCapacity(DEFAULT_CAPACITY);
    }

    public T get(int index) {
        if (index <0 || index >= size())
            return null;

        return items[index];
    }

    public T set(int index, T newVal) {
        if (index < 0 || index >= size()) {
            return null;
        } else {
            T old = items[index];
            items[index] = newVal;
            return old;
        }
    }

    public boolean add(T x) {
        add(size(), x);
        return true;
    }

    public void add(int index, T x) {

        if (items.length == size())
            ensureCapacity(size() * 2 + 1);

        for (int i = size; i > index; i--) {
            items[i] = items[i - 1];
        }

        items[index] = x;
        size++;
    }

    public void remove(int index) {

        //T removeItem=items[index];
        for (int i = index; i < size() - 1; i++) {
            items[i] = items[i + 1];
        }

        size--;
    }

    public static void main(String[] args) {
        MyArrayList<String> list = new MyArrayList<String>();
        list.add("java");
        list.add("c++");
        list.add("c#");
        list.add(2,"php");

        for (int i = 0; i < list.size(); i++)
            System.out.println(list.get(i));
    }
}

LinkedList

  1 package com.hjp.labs;
  2 
  3 public class MyLinkedList<T> {
  4 
  5     /**
  6      * 结点类
  7      */
  8     private static class Node<T> {
  9         T nodeValue; // 数据域
 10         Node<T> next; // 指针域保存着下一节点的引用
 11 
 12         Node(T nodeValue, Node<T> next) {
 13             this.nodeValue = nodeValue;
 14             this.next = next;
 15         }
 16 
 17         Node(T nodeValue) {
 18             this(nodeValue, null);
 19         }
 20     }
 21 
 22     // 下面是SingleLinkedList类的数据成员和方法
 23     private Node<T> head, tail;
 24 
 25     public MyLinkedList() {
 26         head = tail = null;
 27     }
 28 
 29     /**
 30      * 判断链表是否为空
 31      */
 32     public boolean isEmpty() {
 33         return head == null;
 34     }
 35 
 36     /**
 37      * 创建头指针,该方法只用一次!
 38      */
 39     public void addToHead(T item) {
 40         head = new Node<T>(item);
 41         if(tail == null) tail = head;
 42     }
 43 
 44     /**
 45      * 添加尾指针,该方法使用多次
 46      */
 47     public void addToTail(T item) {
 48         if (!isEmpty()) { // 若链表非空那么将尾指针的next初使化为一个新的元素
 49             tail.next = new Node<T>(item); // 然后将尾指针指向现在它自己的下一个元素
 50             tail = tail.next;
 51         } else { // 如果为空则创建一个新的!并将头尾同时指向它
 52             head = tail = new Node<T>(item);
 53         }
 54     }
 55 
 56     /**
 57      * 打印列表
 58      */
 59     public void printList() {
 60         if (isEmpty()) {
 61             System.out.println("null");
 62         } else {
 63             for(Node<T> p = head; p != null; p = p.next)
 64                 System.out.println(p.nodeValue);
 65         }
 66     }
 67 
 68     /**
 69      * 在表头插入结点,效率非常高
 70      */
 71     public void addFirst(T item) {
 72         Node<T> newNode = new Node<T>(item);
 73         newNode.next = head;
 74         head = newNode;
 75     }
 76 
 77     /**
 78      * 在表尾插入结点,效率很低
 79      */
 80     public void addLast(T item) {
 81         Node<T> newNode = new Node<T>(item);
 82         Node<T> p = head;
 83         while (p.next != null) p = p.next;
 84         p.next = newNode;
 85         newNode.next = null;
 86     }
 87 
 88     /**
 89      * 在表头删除结点,效率非常高
 90      */
 91     public void removeFirst() {
 92         if (!isEmpty()) head = head.next;
 93         else System.out.println("The list have been emptied!");
 94     }
 95 
 96     /**
 97      * 在表尾删除结点,效率很低
 98      */
 99     public void removeLast() {
100         Node<T> prev = null, curr = head;
101         while(curr.next != null) {
102             prev = curr;
103             curr = curr.next;
104             if(curr.next == null) prev.next = null;
105         }
106     }
107 
108     /**
109      * <p>插入一个新结点</p>
110      * <ul>插入操作可能有四种情况:
111      * <li>①表为空, 返回false</li>
112      * <li>②表非空,指定的数据不存在</li>
113      * <li>③指定的数据是表的第一个元素</li>
114      * <li>④指定的数据在表的中间</li></ul>
115      * @param appointedItem 指定的nodeValue
116      * @param item 要插入的结点
117      * @return 成功插入返回true;
118      */
119     public boolean insert(T appointedItem, T item) {
120         Node<T>  prev = head, curr = head.next, newNode;
121         newNode = new Node<T>(item);
122         if(!isEmpty()) {
123             while((curr != null) && (!appointedItem.equals(curr.nodeValue))) { //两个判断条件不能换
124                 prev = curr;
125                 curr = curr.next;
126             }
127             newNode.next = curr; //②③④
128             prev.next = newNode;
129             return true;
130         }
131         return false; //
132     }
133 
134     /**
135      * <p>移除此列表中首次出现的指定元素</p>
136      * <ul>删除操作可能出现的情况:
137      * <li>①prev为空,这意味着curr为head. head = curr.next; --> removeFirst();</li>
138      * <li>②匹配出现在列表中的某个中间位置,此时执行的操作是 --> prev.next = curr.next;,</li></ul>
139      * <p>在列表中定位某个结点需要两个引用:一个对前一结点(prev左)的引用以及一个对当前结点(curr右)的引用.</p>
140      * prev = curr;
141      * curr = curr.next;
142      */
143     public void remove(T item) {
144         Node<T> curr = head, prev = null;
145         boolean found = false;
146         while (curr != null && !found) {
147             if (item.equals(curr.nodeValue)) {
148                 if(prev == null) removeFirst();
149                 else prev.next = curr.next;
150                 found = true;
151             } else {
152                 prev = curr;
153                 curr = curr.next;
154             }
155         }
156     }
157 
158     /**
159      * 返回此列表中首次出现的指定元素的索引,如果列表中不包含此元素,则返回 -1.
160      */
161     public int indexOf(T item) {
162         int index = 0;
163         Node<T> p;
164         for(p = head; p != null; p = p.next) {
165             if(item.equals(p.nodeValue))
166                 return index;
167             index++;
168 
169         }
170         return -1;
171     }
172 
173     /**
174      * 如果此列表包含指定元素,则返回 true。
175      */
176     public boolean contains(T item) {
177         return indexOf(item) != -1;
178     }
179 
180     public static void main(String[] args) {
181         MyLinkedList<String> t = new MyLinkedList<String>();
182         t.addToHead("A");
183         //t.addFirst("addFirst");
184         t.addToTail("B");
185         t.addToTail("C");
186         System.out.println(t.indexOf("C")); // 2
187         System.out.println(t.contains("A")); // true
188         //t.addLast("addLast");
189         //t.removeLast();
190         //t.insert("B", "insert");
191         //t.removeFirst();
192         //t.remove("B"); // A C
193         t.printList(); // A B C
194 
195     }
196 }
原文地址:https://www.cnblogs.com/huangjianping/p/8318592.html