zoukankan      html  css  js  c++  java
  • 数据结构和算法:Java实现线性表简单的顺序存储

    一、先定义简单的线性表规则,然后实现

    1、接口

    /**
     * [Project]:moy-gradle-project  <br/>
     * [Email]:moy25@foxmail.com  <br/>
     * [Date]:2018/1/24  <br/>
     * [Description]: 简单的线性表定义<br/>
     *
     * @author YeXiangYang
     */
    public interface SimpleList<E> {
    
        /**
         * 添加元素
         *
         * @param e 需要添加的元素
         * @return 添加成功返回<tt>true<tt/>
         */
        boolean add(E e);
    
        /**
         * 将元素添加到指定下标上,对应下标不存在抛出异常
         *
         * @param index 下标
         * @param e     元素
         * @return 添加成功返回<tt>true<tt/>
         */
        boolean add(int index, E e);
    
        /**
         * 删除最后一个元素,集合为空则抛出异常
         *
         * @return 被删除的元素
         */
        E removeLast();
    
    
        /**
         * 删除指定下标的元素,对应下标不存在抛出异常
         *
         * @param index
         * @return 被删除的元素
         */
        E remove(int index);
    
        /**
         * 删除集合中的对于元素
         *
         * @param e 需要被删除的元素
         * @return 删除成功返回<tt>true<tt/>
         */
        boolean remove(E e);
    
        /**
         * 将指定下标改成对应元素,对应下标不存在抛出异常
         *
         * @param index 下标
         * @param e     需要添加到指定位置为元素
         * @return
         */
        E set(int index, E e);
    
        /**
         * 获取指定下标的元素,对应下标不存在抛出异常
         *
         * @param index 下标
         * @return 下标对应的元素
         */
        E get(int index);
    
        /**
         * 返回元素对应的最小下标
         *
         * @param e 元素
         * @return 返回元素对应的最小下标,不存在返回<tt>-1<tt/>
         */
        int indexOf(E e);
    
        /**
         * 判断集合中是否包含目标元素
         *
         * @param o 目标元素
         * @return 该集合存在目标元素,返回<tt>true<tt/>
         */
        boolean contains(Object o);
    
        /**
         * 获取集合元素个数
         *
         * @return 集合中元素个数
         */
        int size();
    
        /**
         * 判断集合中是否为空
         *
         * @return 集合中为空返回<tt>true<tt/>
         */
        boolean isEmpty();
    
        /**
         * 清除集合中所有元素
         */
        void clear();
    
        /**
         * 重写toString方法
         *
         * @return 返回友好信息
         */
        String toString();
    }
    View Code

    2、实现

    /**
     * [Project]:moy-gradle-project  <br/>
     * [Email]:moy25@foxmail.com  <br/>
     * [Date]:2018/1/23  <br/>
     * [Description]: 简单的线性表顺序存储实现<br/>
     *
     * @author YeXiangYang
     */
    public class SimpleArrayList<E> implements SimpleList<E> {
        private static final int DEFAULT_CAPACITY = 10;
        private transient Object[] data;
        private int size;
    
        public SimpleArrayList() {
            data = new Object[DEFAULT_CAPACITY];
            size = 0;
        }
    
        @Override
        public boolean add(E e) {
            ensureCapacity();
    
            data[size] = e;
            size++;
            return Boolean.TRUE;
        }
    
        private void ensureCapacity() {
            if (size >= data.length) {
                int newLength = data.length << 1;
                Object[] newDataArray = new Object[newLength];
                for (int i = 0; i < size; i++) {
                    newDataArray[i] = data[i];
                    data[i] = null;
                }
                data = newDataArray;
            }
        }
    
        @Override
        public boolean add(int index, E e) {
            if (index < 0 || index > size) {
                throw new IllegalArgumentException("index:" + index + ",size:" + size);
            }
    
            ensureCapacity();
    
            for (int i = size; i > index; i--) {
                data[i] = data[i - 1];
            }
    
            data[index] = e;
            size++;
            return Boolean.TRUE;
        }
    
        @Override
        public E removeLast() {
            return remove(size - 1);
        }
    
        @Override
        public E remove(int index) {
            rangeCheck(index);
    
            E oldData = (E) data[index];
            data[index] = null;
    
            for (int i = index; i < size - 1; i++) {
                data[i] = data[i + 1];
            }
            size--;
            return oldData;
        }
    
        private void rangeCheck(int index) {
            if (index < 0 || index >= size) {
                throw new IllegalArgumentException("index:" + index + ",size:" + size);
            }
        }
    
        @Override
        public boolean remove(E e) {
            int targetIndex = indexOf(e);
            if (targetIndex >= 0) {
                remove(targetIndex);
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }
    
        @Override
        public E set(int index, E e) {
            rangeCheck(index);
    
            E oldData = (E) data[index];
            data[index] = e;
            return oldData;
        }
    
        @Override
        public E get(int index) {
            rangeCheck(index);
    
            return (E) data[index];
        }
    
        @Override
        public int indexOf(E e) {
            if (null == e) {
                for (int i = 0, len = size; i < len; i++) {
                    if (data[i] == null) {
                        return i;
                    }
                }
            } else {
                for (int i = 0, len = size; i < len; i++) {
                    if (e.equals(data[i])) {
                        return i;
                    }
                }
            }
            return -1;
        }
    
        @Override
        public boolean contains(Object o) {
            try {
                E e = (E) o;
                return indexOf(e) >= 0;
            } catch (Exception e) {
                // 转型出错则不包含
            }
            return Boolean.FALSE;
        }
    
        @Override
        public int size() {
            return size;
        }
    
        @Override
        public boolean isEmpty() {
            return 0 == size;
        }
    
        @Override
        public void clear() {
            for (int i = 0; i < size; i++) {
                data[i] = null;
            }
            size = 0;
        }
    
        @Override
        public String toString() {
            if (0 == size) {
                return "[]";
            }
            StringBuilder result = new StringBuilder();
            result.append("[");
            boolean isFirst = Boolean.TRUE;
            for (int i = 0; i < size; i++) {
                if (isFirst) {
                    isFirst = Boolean.FALSE;
                } else {
                    result.append(", ");
                }
                result.append(String.valueOf(data[i]));
            }
            result.append("]");
            return result.toString();
        }
    }

    3、测试

    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * [Project]:moy-gradle-project  <br/>
     * [Email]:moy25@foxmail.com  <br/>
     * [Date]:2018/1/25  <br/>
     * [Description]:
     * <p><br/>
     *
     * @author YeXiangYang
     */
    public class SimpleArrayListTest {
    
        SimpleList<Object> simpleList;
        List<Object> list;
    
        @Before
        public void before() {
            int len = 10;
    
            simpleList = new SimpleArrayList<>();
            list = new ArrayList<>();
    
            insertInitSimpleList(len);
            insertInitList(len);
    
            System.out.println("**************** Before ******************");
            System.out.println("自定义执行测试方法之前:	" + simpleList);
            System.out.println("官方的执行测试方法之前:	" + list);
        }
    
        private void insertInitList(int len) {
            for (int i = 0; i < len; i++) {
                if (len / 2 == i) {
                    list.add(null);
                } else {
                    list.add(i);
                }
            }
        }
    
        private void insertInitSimpleList(int len) {
            for (int i = 0; i < len; i++) {
                if (len / 2 == i) {
                    simpleList.add(null);
                } else {
                    simpleList.add(i);
                }
            }
        }
    
        @After
        public void after() {
            System.out.println("自定义执行测试方法之后:	" + simpleList);
            System.out.println("官方的执行测试方法之后:	" + list);
            System.out.println("**************** After *******************");
            System.out.println();
        }
    
        @Test
        public void addTest() {
            int index = 10;
            Object data = 123;
            try {
                simpleList.add(index, data);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            try {
                list.add(index, data);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Test
        public void removeTest() {
            list.remove(list.size() - 1);
            simpleList.removeLast();
    
            Integer removeData = new Integer("5");
            list.remove(removeData);
            simpleList.remove(removeData);
    
            list.remove(null);
            simpleList.remove(null);
        }
    
        @Test
        public void setTest() {
            int index = 0;
            Object data = 233;
            try {
                System.out.println(simpleList.set(index, data));
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            try {
                System.out.println(list.set(index, data));
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        @Test
        public void getTest() {
            int index = 0;
            try {
                System.out.println(simpleList.get(index));
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            try {
                System.out.println(list.get(index));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Test
        public void isEmptyTest() {
            System.out.println(list.isEmpty());
            System.out.println(simpleList.isEmpty());
        }
    
        @Test
        public void containsTest() {
            Object object = 0;
            System.out.println(list.contains(object));
            System.out.println(simpleList.contains(object));
        }
    
    
        @Test
        public void clearTest() {
            list.clear();
            simpleList.clear();
        }
    }
    View Code

    4、个人总结

         a、这个简单实现是加深自己对线性表的认识,写一遍就知道和源码的差距了,也知道为什么ArrayList查找快,而删除,增加扩容时慢。

         b、查看官方实现java.util.ArrayList源码可知,还需要考虑int类型溢出、扩容的效率、和实现迭代器时,删除,迭代下一个元素要考虑数据正确性等问题。

         c、源码毕竟是源码...

    yexiangyang

    moyyexy@gmail.com


  • 相关阅读:
    java线程池实践
    JAVA中间件(middleware)模式
    [开源]制作docker镜像不依赖linux和Docker环境
    利用浏览器favicon的缓存机制(F-Cache)生成客户端浏览器唯一指纹
    Docker镜像构建原理解析(不装docker也能构建镜像)
    ORM框架对分表分库之分库和分表指定不同的字段
    volatile的内存屏障的坑
    go和python的比较,获取当前时间是今年第几个星期
    c++学生管理系统
    c++学生管理系统(三)
  • 原文地址:https://www.cnblogs.com/moy25/p/8378509.html
Copyright © 2011-2022 走看看