数据结构之自定义线性表 干就完了
Posted 勇敢牛牛不怕困难@帅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之自定义线性表 干就完了相关的知识,希望对你有一定的参考价值。
数据结构与算法之线性表的实现原理及自定义线性表(基于Java基础)
聊一聊算法和数据结构
首先我们明白一个程序的编写过程并不是一下子就能一步完成的,例如举个例子:学生时代必不可少的学生管理系统相关的课程设计作业。采用面向对象的思想,可以把一个学生看成是一个对象,把许多学生的共同特征抽象出来成为一个类,在建立相关的方法。然而在设计中如何来存储一组学生对象呢?在查询中采用什么方法可以更快的查询到该学生呢?等等。其实在每一个步骤的设计过程中都会考虑的算法和数据结构。所以我们可以将一个程序=算法+数据结构。
什么是数据结构呢?
但凡有数据扎堆的地方,就有数据结构的影子,但凡有数据结构的地方,就脱不了算法的“折磨”。
数据结构就是将一组懒散的数据规格化,理论上来讲更便于管理。就好比现实生活中的排队购票,排队打疫苗等等,如果不排队,而是一拥而上的话,将会大大降低其速度。在排队的过程中,就可以看成是一种队列先进先出,先来的先打疫苗。
数据结构主要学习的是数据之间的关系、关系在计算机上的存储、对数据的具体操作和使用场景。
数据之间的逻辑关系-----线性结构、树形结构、图形结构
关系在计算机上的存储----物理结构----顺序存储结构、链式存储结构
什么是算法?
算法是解决特定问题求解步骤的描述,分析问题一步一步求解,并得到结果,这一系列的步骤称为算法。
大展身手->线性表
线性表的定义
零个或多个元素的有限序列例如下图:
除了第1个元素a1之外,其他元素都有唯一的直接前驱,同理除了第n个元素an之外,其他元素都有唯一的直接后继,n表示线性表的长度,当n=0时,称为空表!
自定义线性表接口
既然线性结构可以由顺序存储结构和链式结构实现,那么将两者对线性结构的共同的操作进行抽取,定义出线性结构的接口。
代码实现如下:
public interface List<E> extends Iterable<E> {
public void add(E element);//在表的末尾增添一个元素
public void add(int index,E element);//在指定位置添加一个元素
public void remove(E element);//移除指定的元素
public E remove (int index);//移除指定下标的元素并返回
public E get(int index);//获取指定下标的元素
public int size();//获取数组中的有效长度
public int indexOf(E element);//查找指定元素的下标
public boolean contains(E element);//判断元素是否在线性表中
public boolean isEmpty();//判断线性表是否为空
public void clear();//清空线性表
public void sort(Comparator<E> c);//线性表进行排序
public List<E> subList(int fromIndex,int toIndex);//截取子线性表
}
线性表的实现ArrayList
ArrayList就是线性结构顺序存储方式的具体实现,称为线性表,创建ArrayList类实现List接口,定义相关的属性和构造方法。
package muself_list;
import java.lang.reflect.Array;
import java.util.Comparator;
import java.util.Iterator;
public class ArrayList<E> implements List<E>{
//存储元素的容器
private E[] data;
//元素的有效个数
private int size;
//默认容量的大小
private static int DEFAULT_CAPACITY = 10;
public ArrayList() {//无参构造方法,且默认长度为10
// TODO 自动生成的构造函数存根
this(DEFAULT_CAPACITY);
}
public ArrayList(int capacity) {//有参构造方法,默认长度为capacity
if(capacity<0) {
throw new IllegalArgumentException("initial capacity must >0");
}
data = (E[])new Object[capacity];
size = 0;
}
public ArrayList(E[] arr) {//有参构造方法,默认长度为arr.length
if(arr==null) {
throw new IllegalArgumentException("initial arr can not null!");
}
data = (E[])new Object[arr.length];
size = 0;
for(E e:arr) {
add(e);
}
}
@Override
public Iterator<E> iterator() {
// TODO 自动生成的方法存根
return null;
}
@Override
public void add(E element) {
// TODO 自动生成的方法存根
add(size,element);
}
@Override
public void add(int index, E element) {
// TODO 自动生成的方法存根
if(index<0||index>size) {
throw new IllegalArgumentException("add index must 0<=index<=size!");
}
if(size==data.length) {
resize(data.length*2);
}
for(int i =size;i>index;i--) {
data[i] = data[i-1];
}
data[index] = element;
size++;
}
private void resize(int newlength) {
E[] newData = (E[])new Object[newlength];
for(int i=0;i<size;i++) {
newData[i] = data[i];
}
data = newData;
}
@Override
public void remove(E element) {
// TODO 自动生成的方法存根
int index = 0;
while((index=indexOf(element))!=-1) {
remove(index);
}
}
@Override
public E remove(int index) {
// TODO 自动生成的方法存根
if(index<0||index>size) {
throw new IllegalArgumentException("add index must 0<=index<=size!");
}
E ret = get(index);
for(int i = index;i<size-1;i++ ) {
data[i] = data[i+1];
}
size--;
if(size == data.length/4&&data.length>DEFAULT_CAPACITY) {
resize(data.length/2);
}
return ret;
}
@Override
public E get(int index) {
// TODO 自动生成的方法存根
if(index<0||index>size) {
throw new IllegalArgumentException("add index must 0<=index<=size!");
}
return data[index];
}
@Override
public E set(int index, E element) {
// TODO 自动生成的方法存根
if(index<0||index>size) {
throw new IllegalArgumentException("add index must 0<=index<=size!");
}
E ret = data[index];
data[index] = element;
return ret;
}
@Override
public int size() {
// TODO 自动生成的方法存根
return size;
}
@Override
public int indexOf(E element) {
// TODO 自动生成的方法存根
for(int i=0;i<size;i++) {
if(element.equals(data[i])) {
return i;
}
}
return -1;
}
@Override
public boolean contains(E element) {
// TODO 自动生成的方法存根
return indexOf(element)!=-1;
}
@Override
public boolean isEmpty() {
// TODO 自动生成的方法存根
return size==0;
}
@Override
public void clear() {
// TODO 自动生成的方法存根
data =(E[]) new Object[DEFAULT_CAPACITY];
size = 0;
}
@Override
public void sort(Comparator<E> comparator) {
//在这里采用的是插入排序的思想,以第一个元素作为比较对象,从下标1开始,i控制外成循环,j则去比对和i之前的数进行比较
// TODO 自动生成的方法存根
if(comparator==null) {
throw new IllegalArgumentException("comparator can not null");
}
for(int i=1;i<size;i++) {
E e = data[i];
int j;
for(j=i;j>0&&comparator.compare(data[j-1], e)>0;j--) {
data[j] = data[j-1];
}
data[j] = e;
}
}
@Override
public List<E> sublist(int formIndex, int toIndex) {
// TODO 自动生成的方法存根
if(formIndex<0||formIndex>=toIndex||formIndex>=size) {
throw new IllegalArgumentException("sublist index outof range");
}
ArrayList<E> list = new ArrayList<>();
for(int i = formIndex;i<toIndex;i++) {
list.add(data[i]);
}
return list;
}
@Override
public String toString() {
// TODO 自动生成的方法存根
StringBuilder sb = new StringBuilder();
sb.append('[');
if(isEmpty()) {
sb.append(']');
}else {
for(int i=0;i<size;i++) {
sb.append(data[i]);
sb.append(',');
}
sb.append(']');
}
return sb.toString();
}
@Override
public boolean equals(Object obj) {
// TODO 自动生成的方法存根
if(obj==null) return false;
if(obj==this) return true;
if(obj instanceof ArrayList) {
ArrayList<E> other = (ArrayList<E>)obj;
if(other.size()==size) {
for(int i=0;i<size;i++) {
if(!this.data[i].equals(other.data[i])) {
return false;
}
}
return true;
}else {
return false;
}
}
return false;
}
//返回迭代器的对象
public Iterator<E> iterator1(){
return new ArrayListIterator();
}
private class ArrayListIterator implements Iterator<E>{
private int cur =0;
public boolean hasNext() {
return cur<size;
}
public E next() {
return data[cur++];
}
}
}
测试代码
package muself_list;
import java.util.Comparator;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Integer [] arr1= {3,4,5,6,7,8};
Integer [] arr2= {3,4,5,6,7,8,11,2,3};
ArrayList<Integer> array1 = new ArrayList<>(arr1);
ArrayList<Integer> array2 = new ArrayList<>(arr2);
array1.sort(new Comparator<Integer>() {
@Override
public int compare(Integer arg0, Integer arg1) {
// TODO 自动生成的方法存根
return arg1-arg0;
}
});
Iterator<Integer> it = array1.iterator1();
while(it.hasNext()) {
System.out.println(it.next().toString());
}
System.out.println(array1.toString());
}
}
总结
这样一个自定义的线性表就创建成功了,虽然java的API自带了List接口以及ArrayList顺序存储的线性表。其实从本质上来看,ArrayList的底层原理就是一个对象数组在进行增删改查的操作,不过只是将这个对象数组封装在内部,且隐藏于内部就是私有化,只能内部自己使用。总的来讲线性表实现原理和过程并不是特别的难,其实就是在数组基础上的修改。
以上是关于数据结构之自定义线性表 干就完了的主要内容,如果未能解决你的问题,请参考以下文章
153-模型-日期表兼容农历之自定义函数 fxCalendar