数据结构之顺序表

来源:互联网 发布:广联达软件安装 编辑:程序博客网 时间:2024/06/05 17:27

注:总结自《数据结构》
(1)顺序表的概念:
1.数据结构中的顺序表是采用数组来实现的,熟悉数组的同学也就很快会明白顺序表的原理。
创建数组有两种方式:
第一种是先指定数组的长度,每个位置有默认值,后根据需要为每个位置添加元素。

int[] array = new int[8];for(int i = 0;i < array.length;i++){      array[i] = i;}

第二种是直接指定每个位置上的元素

int array[] = {1,2,3,4,5};

2.向顺序表中追加元素:如果数组已经满了,再追加元素就需要扩充容量。需要建立一个有两倍容量的数组,复制原来的元素,再添加新的元素。
3.向顺序表中某个位置i添加元素:将i位置开始及之后的元素向后移动一位,然后将新元素放在位置i。
4.删除顺序表中位置i的元素:将位置i之后的元素向前移动一位,
5.可以根据下标查找元素,也可以设置i位置的元素。
6.顺序表查找元素的时间复杂度是O(1),删除元素和插入元素都需要移动元素,时间复杂度是O(n)。

(2)顺序表的实现

/** * @date 2017-5-31 * @author liuffei * @description 顺序表,用数组表示 */public class SeqList<T> implements LList<T> {    private Object[] element;    private int len;    /**     * 浅拷贝     * @param list    public SeqList(SeqList<T> list){        this.element = list.element;        this.len = list.len;    }    */    /**     * 深拷贝     * @param list     */    public SeqList(SeqList<T> list){        this.len = list.len;        this.element = new Object[list.element.length];        for(int i = 0;i < list.element.length;i++){            this.element[i] = list.element[i];        }    }    /**s     * 构造长度为size的顺序表     * @param size 长度     */    public SeqList(int size){        this.element = new Object[size];        this.len = 0;    }    @Override    public boolean isEmpty() {        return this.len == 0;    }    @Override    public void insert(int i, T t) {        if(null == t){            return;        }        //数组已经满了,需要扩大容量        if(this.len == element.length ){            Object newEle[] = new Object[this.len*2];            for(int j = 0;j < this.len;j++){                //拷贝数组元素                newEle[j] = element[j];            }            //添加元素            newEle[i] = t;            //重新指向一个新的数组            element = newEle;        }else{            //原数组中i之后的元素都要向后移动一位            for(int j = this.len-1;j >=i;j--){                element[j+1] = element[j];            }            element[i] = t;            this.len++;        }    }    @Override    public void set(int i, T t) {        if(null == t){            return;        }        if(i >=0 && i < this.len){            element[i] = t;        }else{            //抛出序号越界异常            throw new IndexOutOfBoundsException(i+"");        }    }    public String toString(){        StringBuffer str = new StringBuffer("(");        for(int i = 0;i < this.len;i++){            str.append(element[i] + ",");        }        str.deleteCharAt(str.length()-1);        str.append(")");        return str.toString();    }    @Override    public T get(int i) {        if(i >=0 && i < this.len){            return (T) element[i];        }        return null;    }    @Override    public int length() {        return this.len;    }    @Override    public T remove(int i) {        if(i < 0 || i >= this.len || this.len == 0){            return null;        }        T old = (T) element[i];        for(int j = i;j < this.len - 1;j++){            element[j] = element[j+1];        }        element[this.len-1] = null;        this.len--;        return old;    }    @Override    public void removeAll() {        this.len = 0;    }    @Override    public T search(T key) {        return null;    }    @Override    public void append(T t) {        insert(this.len,t);    }    public boolean equals(Object obj){        if(this == obj){            return true;        }        if(obj instanceof SeqList){            SeqList<T> list = (SeqList<T>) obj;            if(list.length() == this.length()){                for(int i = 0;i < this.length();i++){                    if(!list.get(i).equals(this.get(i))){                        return false;                    }                }                return true;            }        }        return false;    }    public static void main(String args[]){        SeqList<String> list = new SeqList<String>(4);         String str = "aaa";        list.append(str);        list.append("bbb");        list.append("ccc");        list.append("ddd");        SeqList<String> copyList = new SeqList<String>(list);        list.set(2,"eee");        System.out.println(list.toString());        System.out.println(copyList.toString());    }}

(3)顺序表的深拷贝和浅拷贝
1.深拷贝
当一个类包含引用类型的成员变量时,该类声明的拷贝构造函数,不仅要复制对象的所有基本类型成员变量值,还要重新申请引用类型变量占用的动态存储空间,并复制其中所有对象,这种复制方式成为深拷贝。

/** * 深拷贝 * @param list */public SeqList(SeqList<T> list){    this.len = list.len;    this.element = new Object[list.element.length];    for(int i = 0;i < list.element.length;i++){        this.element[i] = list.element[i];    }}

2.浅拷贝
如果一个类将拷贝构造方法实现为逐域拷贝,即将当前对象的各成员变量值赋值为实际参数对应各成员变量值,称为浅拷贝。
当成员变量的数据类型是基本数据类型时,浅拷贝能够实现对象赋值功能。由于Java的数组和类是引用数据类型,两个数组/对象之间的赋值是引用赋值,数组赋值过程中没有申请新的存储空间,对象赋值过程没有创建新的实例。浅拷贝只复制了对象引用,没有实现对象复制功能。两个对象拥有同一个引用,造成修改、插入、删除等功能的相互影响。

/** * 浅拷贝 * @param list */public SeqList(SeqList<T> list){    this.element = list.element;    this.len = list.len;}

3.测试
深拷贝运行结果:
这里写图片描述
浅拷贝运行结果:
这里写图片描述

原创粉丝点击