zoukankan      html  css  js  c++  java
  • java线性表学习笔记(一)

    线性表是一种按顺序储存数据是的常用结构,大多数的线性表都支持以下的典型操作:

    从线性表提取插入删除一个数据;

    找出线性表中的某一个元素;

    找出线性表中的元素;

    确定线性表中是否包含某一个元素,确定线性表是否为空;

    实现线性表的方法有两种:

    1、数组(arry),数组是动态的创建的,如果元素超过了数组的容量,就会创建一个新的数组并且把当前的数组元素复制到更大的数组里;

    2、连式结构(linked structure)。连式结构有节点构成,节点是动态创建的。

    方便起见,把数组称为MyArrayList,把连式结构称为MylinkedList,他们有相同的操作,却有这不同的实现。

    设计一个好用的线性表,通常把一些通用的操作归纳为一个接口和抽象类,抽象类提供接口实现的框架,以更好地实现接口。把这样的接口叫MyList,把这样的抽象类叫MyAbstractList。

    以下是接口MyList的代码:

    public interface MyList<E> {    
        public void add(E e);             
        public void add(int index,E e);    
        public void clear();          //清除所有元素
        public boolean contains(E e);       
        public E get(int index);
        public int indexOf(E e);    
        public boolean isEmpty();    
        public int lastIndexOf(E e);    
        public boolean remove(E e);    
        public E remove(int index);           //删除指定元素
        public Object set(int index, E e);     //在指定位置插入元素
        public int size();            
    }

    下面是MyAbstractList代码(实现了各方法):

    public abstract class MyAbstractList<E> implements MyList<E> {
        protected int size = 0;   //声明size
        
        protected MyAbstractList(){}
        protected  MyAbstractList(E[] objects){
            for(int i = 0;i<objects.length;i++){
                add(objects[i]);
            }
        }
        public void add(E e){
            add(size,e);
        }
        public boolean isEmpty(){
            return size==0;
            
        }
        public int size(){
            return size;
        }
        public boolean remove(E e){
            if(indexOf(e) >=0){
                remove (indexOf(e));
                return true;            
            }
            else
                return false;
        }
    }

    下面先讲数组的线性表示:

    数组是一种固定大小的数据结构,一旦创建就无法改变,但仍然可以用数组来实现动态的数据结构,方法是当数组大小不够用的时候,就创建一个更大的数组类来替换当前数组。

    初始状态时,默认大小,创建一个类型为E[ ] 的数组data。向数组中插入一个新的元素时,首先确认数组是否有足够的空间,若不够,则创建一个为当前数组两倍的数组,然后复制元素到新的数组里面。现在在指定的下标处插入新的元素,并且要将指定下标后面的所有元素的下标都增加一。若是删除元素,则要把后面元素下标都减少一。

    大体思路是:

    + MyArrayList()   创建默认数组

    +MyArrayList(E[ ] objects)   由对象数组创建一个数组

    —ensureCapacity()    如果需要就扩大数组

    +trimToSize()    将数组大小缩小至线性表的当前大小

    下面是MyArrayList实现MyAbstractList的代码:

    public class MyArrayList<E> extends MyAbstractList<E> {
          public static final int INITIAL_CAPACITY = 16;    //定义初始容量
          private E[] data = (E[])new Object[INITIAL_CAPACITY];
    
          //创建默认数组
          public MyArrayList() {
          }
    
          //由对象数组创建一个数组
          public MyArrayList(E[] objects) {
            for (int i = 0; i < objects.length; i++)
              add(objects[i]); // Warning: don抰 use super(objects)! 
          }
    
          //在指定下标处增加元素
          public void add(int index, E e) {
             //如果需要调用数组增加两倍的方法
            ensureCapacity();          
    
            // 把指定下标后面的数的下标全部加一
            for (int i = size - 1; i >= index; i--)
              data[i + 1] = data[i];
            data[index] = e;
            size++;
          }
    
          //如果需要,数组增加两倍的方法
          private void ensureCapacity() {
            if (size >= data.length) {
              E[] newData = (E[])(new Object[size * 2 + 1]);
              System.arraycopy(data, 0, newData, 0, size);
              data = newData;
            }
          }
          //清空元素
          public void clear() {
            data = (E[])new Object[INITIAL_CAPACITY];
            size = 0;
          }
    
          //是否包含某一元素的方法
          public boolean contains(E e) {
            for (int i = 0; i < size; i++)
              if (e.equals(data[i])) return true;
    
            return false;
          }
    
          //给定下标,获得下标所指定的元素
          public E get(int index) {
            return data[index];
          }
    
         //从第一个元素开始搜索某一元素 ,有则返回下标值,否则返回-1
          public int indexOf(E e) {
            for (int i = 0; i < size; i++)
              if (e.equals(data[i])) return i;
    
            return -1;
          }
    
          //从最后一个元素开始 
          public int lastIndexOf(E e) {
            for (int i = size - 1; i >= 0; i--)
              if (e.equals(data[i])) return i;
    
            return -1;
          }
    
          //删除元素
          public E remove(int index) {
            E e = data[index];
            
            for (int j = index; j < size - 1; j++)
              data[j] = data[j + 1];
            
            //最后一个元素为空
            data[size - 1] = null; 
            size--;
            return e;
          }
    
          //替换
          public E set(int index, E e) {
            E old = data[index];
            data[index] = e;
            return old;
          }
    
         //重写Object中的方法,返回一个表示包含数组中全部元素的字符串
          public String toString() {
            StringBuilder result = new StringBuilder("[");
    
            for (int i = 0; i < size; i++) {
              result.append(data[i]);
              if (i < size - 1) result.append(", ");
            }
    
            return result.toString() + "]";
          }
    
          //将数组大小缩小至线性表的当前大小
          public void trimToSize() {
            if (size != data.length) { 
              E[] newData = (E[])(new Object[size]);
              System.arraycopy(data, 0, newData, 0, size);
              data = newData;
            }
      }
    }

    测试的一个事例:

    public class TestList {
        public static void main(String[] args) {
            //创建一个线性表
            MyList<String> list = new MyArrayList<String>();
            
            //加入一个元素
            list.add("喜欢");
            list.add(0,"我");
            list.add("你");
            System.out.println(list);
            
            list.add(1,"非常");
            list.add(1,"很");
            System.out.println(list);
            
            list.remove(1);
            System.out.println(list);
            
            list.set(3, "你 ,爱你一万年");
            System.out.println(list);
            
        }
    }

    再来讲链表:

    由于MyArrayList是有数组实现的,在使用get()、set函数会是  高效的,但是在用add()和remove时效率却并不高,因为可能要移动大量的元素。为提高效率,可以采用链式结构来实现线性表。东西有点多,写到笔记二去吧。

  • 相关阅读:
    OAuth2.0协议封装类
    FFmpeg学习笔记
    mysql学习笔记(有待增补)
    使用cnpm国内淘宝镜像命令
    mongoDB中的聚合操作示例
    react的学习日常整理
    服务器防止访问超时的一些参数设置
    MongoDB基本语句操作
    CI框架配置多个数据库
    php前后台登录交互明文传输使用base64加密
  • 原文地址:https://www.cnblogs.com/LZYY/p/3274858.html
Copyright © 2011-2022 走看看