• 手写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 }
  • 相关阅读:
    推荐一个wpf&sliverlight的图表控件
    数独求解
    WPF中的 CollectionChanged事件通知
    Windows 7 任务栏之缩略图预览(Thumbnail)
    把Google HK设为IE默认的搜索引擎
    F#小记——1. Hello F#
    F#小记——2. 基本数据类型
    使用异步socket的时候需要注意memory spike
    《everytime you kissed me》的中文歌词
    我回来了o(∩_∩)o...
  • 原文地址:https://www.cnblogs.com/huangjianping/p/8318592.html
Copyright © 2020-2023  润新知