zoukankan      html  css  js  c++  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、实现

    package com.moy.data.structure.list;
    
    
    /**
     * [Project]:moy-gradle-project  <br/>
     * [Email]:moy25@foxmail.com  <br/>
     * [Date]:2018/1/27  <br/>
     * [Description]: <br/>
     *
     * @author YeXiangYang
     */
    public class SimpleLinkedList<E> implements SimpleList<E> {
        private int size;
        private transient Node<E> first;
        private transient Node<E> last;
    
        @Override
        public boolean add(E e) {
            return add(size, e);
        }
    
        @Override
        public boolean add(int index, E e) {
            if (index < 0 || index > size) {
                throw new IllegalArgumentException("index:" + index + ",size:" + size);
            }
            if (null != first) {
                if (0 == index) {
                    Node<E> newData = new Node<>(e, first);
                    first = newData;
                } else if (size == index) {
                    Node<E> newData = new Node<>(e, null);
                    last.next = newData;
                    last = newData;
                } else {
                    Node<E> prevNode = getNode(index - 1);
                    Node<E> oldNode = prevNode.next;
                    Node<E> newData = new Node<>(e, oldNode);
                    prevNode.next = newData;
                }
            } else {
                Node<E> newData = new Node<>(e, null);
                this.first = newData;
                this.last = newData;
            }
            size++;
            return Boolean.TRUE;
        }
    
        @Override
        public E removeLast() {
            return remove(size - 1);
        }
    
        @Override
        public E remove(int index) {
            rangeCheck(index);
            E oldData = null;
            if (0 == index) {
                oldData = first.data;
                first.data = null;
                first = first.next;
            } else if (size - 1 == index) {
                Node<E> lastNode = getNode(index - 1);
                lastNode.next = null;
                oldData = last.data;
                last.data = null;
                last = lastNode;
            } else {
                Node<E> lastNode = getNode(index - 1);
                Node<E> currentNode = lastNode.next;
                Node<E> nextNode = currentNode.next;
                lastNode.next = nextNode;
                oldData = currentNode.data;
                currentNode.data = null;
                currentNode.next = null;
            }
            size--;
            return oldData;
        }
    
        @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) {
            Node<E> node = getNode(index);
            E oldData = node.data;
            node.data = e;
            return oldData;
        }
    
        @Override
        public E get(int index) {
            Node<E> node = getNode(index);
            return node.data;
        }
    
        private Node<E> getNode(int index) {
            rangeCheck(index);
            Node<E> current = this.first;
            if (null != current) {
                int dataIndex = -1;
                while (null != current) {
                    dataIndex++;
                    if (dataIndex == index) {
                        return current;
                    }
                    current = current.next;
                }
            }
            throw new IllegalArgumentException("index:" + index + ",size:" + size);
        }
    
        private void rangeCheck(int index) {
            if (index < 0 || index >= size) {
                throw new IllegalArgumentException("index:" + index + ",size:" + size);
            }
        }
    
        @Override
        public int indexOf(E e) {
            if (null != first) {
                int index = -1;
                Node<E> current = this.first;
                do {
                    index++;
                    if (null == e) {
                        if (null == current.data) {
                            return index;
                        }
                    } else {
                        if (e.equals(current.data)) {
                            return index;
                        }
                    }
                    current = current.next;
                } while (null != current);
            }
            return -1;
        }
    
        @Override
        public int size() {
            return size;
        }
    
        @Override
        public boolean isEmpty() {
            return 0 == size;
        }
    
        @Override
        public boolean contains(Object o) {
            try {
                E e = (E) o;
                return indexOf(e) >= 0;
            } catch (Exception e) {
                // 转型出错则不包含
            }
            return Boolean.FALSE;
        }
    
        @Override
        public void clear() {
            if (null != first) {
                Node<E> currentNode = this.first;
                while (null != currentNode) {
                    currentNode.data = null;
                    currentNode = currentNode.next;
                }
            }
            first = null;
            last = null;
            size = 0;
        }
    
        private static class Node<E> {
            Node<E> next;
            E data;
    
            public Node(E data, Node<E> next) {
                this.next = next;
                this.data = data;
            }
        }
    
        public SimpleLinkedList() {
            first = null;
            last = null;
            size = 0;
        }
    
        @Override
        public String toString() {
            if (null == first) {
                return "[]";
            }
            StringBuilder result = new StringBuilder();
            Node<E> currentNode = this.first;
            boolean isFirst = Boolean.TRUE;
            do {
                if (isFirst) {
                    result.append("[");
                    isFirst = Boolean.FALSE;
                } else {
                    result.append(", ");
                }
                result.append(String.valueOf(currentNode.data));
                currentNode = currentNode.next;
            } while (null != currentNode);
            result.append("]");
            return result.toString();
        }
    }

    3、测试

    package com.moy.data.structure;
    
    import com.moy.data.structure.list.SimpleLinkedList;
    import com.moy.data.structure.list.SimpleList;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import java.util.LinkedList;
    import java.util.List;
    
    /**
     * [Project]:moy-gradle-project  <br/>
     * [Email]:moy25@foxmail.com  <br/>
     * [Date]:2018/1/28  <br/>
     * [Description]:
     * <p><br/>
     *
     * @author YeXiangYang
     */
    public class SimpleLinkedListTest {
    
        SimpleList<Object> simpleList;
        List<Object> list;
    
        @Before
        public void before() {
            int len = 10;
    
            simpleList = new SimpleLinkedList<>();
            list = new LinkedList<>();
    
            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 {
                System.out.println(simpleList.add(index, data));
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            try {
                list.add(index, data);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Test
        public void removeTest() {
            System.out.println(list.remove(list.size() - 1));
            System.out.println(simpleList.removeLast());
    
    
            Integer removeData = new Integer("7");
            System.out.println(list.remove(removeData));
            System.out.println(simpleList.remove(removeData));
    
            System.out.println(list.remove(null));
            System.out.println(simpleList.remove(null));
        }
    
        @Test
        public void setTest() {
            int index = 0;
            Object data = 2333;
            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、实现简单的链式线性表来加深印象,使用链式存储的好处是不用担心扩容问题、新增和删除操作也不用进行数组位移,但是查找元素还是要遍历所有元素

         b、查看官方实现java.util.LinkedList可知,其实现使用双向节点,在查询也做了优化,根据元素位置和链表总个数,决定从头节点还是尾节点开始查询

    yexiangyang

    moyyexy@gmail.com


     

  • 相关阅读:
    java_oop_方法2
    POJ 3276 Face The Right Way(反转)
    POJ 3276 Face The Right Way(反转)
    POJ 2566 Bound Found(尺取法,前缀和)
    POJ 2566 Bound Found(尺取法,前缀和)
    POJ 3320 Jessica's Reading Problem(尺取法)
    POJ 3320 Jessica's Reading Problem(尺取法)
    POJ 3061 Subsequence(尺取法)
    POJ 3061 Subsequence(尺取法)
    HDU 1222 Wolf and Rabbit(欧几里得)
  • 原文地址:https://www.cnblogs.com/moy25/p/8506231.html
Copyright © 2011-2022 走看看