数据结构与算法2:线性结构与线性表-顺序表

来源:互联网 发布:串口接收和发送数据 编辑:程序博客网 时间:2024/05/18 04:04

线性结构


线性结构是一个数据元素的有序集合。它有四个基本特征

  • 集合中必存在唯一的一个”第一个元素”
  • 集合中必存在唯一的一个”最后的元素”
  • 除最后元素之外,其它数据元素均有唯一的”后继”
  • 除第一元素之外,其它数据元素均有唯一的”前扑”

线性表

线性表是最基本、最简单、也是最常用的一种数据结构。
线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。

顺序表

元素的存储空间是连续的。在内存中是以顺序存储,内存划分的区域是连续的。存储结构如下图:
这里写图片描述

实现代码,简单实现增加 移除……操作

import java.io.Serializable;import java.util.Arrays;/** * 顺序表 * @author admin * * @param <E> */public class ArrayList<E> implements Serializable {    private static final long serialVersionUID = 8233103956132228603L;    /**     * 定义一个顺序结构的允许最大容量,这里参考了jdk源码的方法,官方文档解释说      * Object[]的最大容量一般收到VMs的限制,推荐设置为Integer.MAX_VALUE-8     */    private static final int MAX_SIZE = Integer.MAX_VALUE-1;    /**     * ArrayList的大小     */    private int size;    /**     * 存储数据的实际长度     */    private int currentSize = -1;    /**     * 存放数据的数组     */    private Object[] elementData;    /**     * 默认初始化方法,默认设置Object的初始大小为10     */    public ArrayList(){        this.size = 10;    }    /**     * 构造方法,指定初始容量大小     * @param initCapacity 初始化容量     */    public ArrayList(int initCapacity) {        if(initCapacity < 0)            throw new RuntimeException("容量数值小于0");        if(initCapacity > MAX_SIZE)             throw new RuntimeException("超出最大容量");        this.elementData = new Object[initCapacity];        this.size = initCapacity;    }    /**     * 扩展容量,确保容量不超过初始化容量     * @param requireCapacity     */    private void ensureCapacity(int requireCapacity){          if(requireCapacity < 0)              throw new ExceptionInInitializerError();          if(requireCapacity >= this.size){              int newCapacity = requireCapacity+10;  // 每次扩展容量只扩展10个单位的容量。              if(newCapacity > MAX_SIZE){                  newCapacity = requireCapacity + (10 - (newCapacity - MAX_SIZE)); // 重新计算新的容量              }              this.size = newCapacity;              elementData = Arrays.copyOf(elementData, newCapacity);                }      }      /**     * 获取顺序表的容量     * @return     */    public int getSize() {        return this.size;    }    /**     * 获取顺序表实际存储长度     * @return     */     public int getCurrentSize() {         return this.currentSize;     }     /**      * 判断当前表是否为空      * @return      */     public boolean isEmpty() {         return (this.currentSize == -1);     }     /**       * 判断索引的范围       * @param index 需要判断的索引       */       private void checkRange(int index){           if(index<0 || index > currentSize)               throw new ArrayIndexOutOfBoundsException();       }     /**       * 增加泛型的支持,使每个放入ArrayList容器的元素不会丢失其数据类型       * @param index       * @return E       */       @SuppressWarnings("unchecked")        private E elementData(int index) {         checkRange(index);           return (E) elementData[index];       }     /**      * 往顺序表ArrayList尾部添加元素的方法。       * @param e      * @return      */     public boolean add(E e) {         this.ensureCapacity(currentSize + 1);         this.elementData[currentSize + 1] = e;         currentSize ++;         return true;     }     /**      * 获取元素所在的索引位置      * @param e      * @return      */     public int indexOf(Object e) {         if(e == null || e == "" || e.equals(null) || "".equals(e)) {             return -1;         } else {             for (int i = 0; i <=currentSize; i++) {                if(e.equals(elementData[i]) || e.hashCode()==elementData[i].hashCode())                    return i;            }         }         return -1;     }     /**      * 移除一个元素      * @param e      * @return      */     public boolean removeElement(E e) {         int index = indexOf(e);         if(index > 0) {             elementData[index] = null;             currentSize--;         }         return false;     }     /**      * 移除所有元素      * @return      */     public boolean removeAll() {         for (int i = 0; i < currentSize; i++) {             elementData[i] = null;         }         currentSize = -1;         return true;     }}
0 0