线性结构的定义
若结构是非空有限集,则有且仅有一个开始结点和一个终端结点,并且所有结点都最多只有一个直接前趋和一个直接后继。
可表示为:(a1 , a2 , ……, an)
线性结构的特点
① 只有一个首结点和尾结点;
② 除首尾结点外,其他结点只有一个直接前驱和一个直接后继
简言之,线性结构反映结点间的逻辑关系是 一对一的
线性结构包括线性表、堆栈、队列、字符串、数组等等,其中,最典型、最常用的是线性表
线性表的定义
同一线性表中的元素必定具有相同特性
线性表的重要基本操作
初始化、取值、查找、插入、删除
取值:根据位置 i 获取相应位置数据元素的内容
查找:根据指定数据获取数据所在的位置
插入:插在第 i 个结点之前
删除:删除第 i 个结点
线性表的实现
线性表(容器):本质:就是一个对象数组
模板:
public class MyArrayList<E> {
private Object[] data; // 保存线性表数据的数组
private int capacity; // 线性表目前的容量
private int size; // 线性表的元素个数
/**
* 初始化未声明大小,声明为10
*/
public MyArrayList() {
this(10);
}
/**
* 初始化线性表,声明数组的大小
* @param initSize 线性表的初始化大小
*/
public MyArrayList(int initSize) {
if (initSize >= 0) {
data = new Object[initSize];
capacity = initSize;
size = 0;
} else {
throw new RuntimeException("初始化大小不能小于0: " + initSize);
}
}
/**
* 判断当前线性表是否为空
* @return
*/
public boolean isEmpty() {
if (size > 0) {
return false;
} else {
return true;
}
}
/**
* 返回当前线性表的大小
* @return
*/
public int capacity() {
return size;
}
/**
* 清空当前线性表
*/
public void empty() {
data = null;
capacity = 0;
size = 0;
}
/**
* 末位添加新元素
* @param e 元素e
*/
public boolean add(E e) {
validatecp();
data[size] = e;
size++;
return true;
}
/**
* 判断是否超出容量,即size是否超出capacity,如果超出则扩容
*/
private void validatecp() {
if (size == capacity) {
capacity *= 2;
Object[] temp = new Object[capacity];
for (int i = 0; i < size; i++) {
temp[i] = data[i];
}
data = temp;
}
}
/**
* 判断下标是否在正常范围内
* @param index 接收的下标参数
*/
private void validateindex(int index) {
if (index < 0 || index > size) {
throw new RuntimeException("无效的下标: " + index);
}
}
/**
* 取得某个位置元素
* @param index 下标参数
* @return
*/
public E getElement(int index) {
validateindex(index);
return (E) data[index];
}
/**
* 在指定的位置插入元素
* @param index 元素的插入位置
* @param e 元素
* @return
*/
public boolean insert(int index, E e) {
validateindex(index);
validatecp();
for (int i = size; i > index; i--) {
data[i] = data[i - 1];
}
data[index] = e;
size++;
return true;
}
/**
* 删除指定位置的元素
* @param index 待删除元素下标
* @return
*/
public boolean delete(int index) {
validateindex(index);
for (int i = index; i < size; i++) {
data[i] = data[i + 1];
}
data[size - 1] = null;
size--;
return true;
}
@Override
public String toString() {
String str = "[ ";
for (Object e : data) {
if (e != null) {
str = str + e + " ";
}
}
str = str + "]";
return str;
}
}
自己创建一个线性表:
/**
*
* @author Admin
*
*/
public class LanqiaoArrayList {
/*
* 保存元素
*/
private Object[] data;
/*
*线性表的容量
*/
private int capacity;
/*
*线性表中元素的个数
*/
private int size;
/*
* 不指定线性表的容量,采用默认值
*/
public LanqiaoArrayList() {
data = new Object[10];
capacity = 10;
size = 0 ;
}
/**
* 指定线性表的容量
* @param initCapacity 线性表容量
*/
public LanqiaoArrayList(int initCapacity) {
if(initCapacity >= 0) {
data = new Object[initCapacity];
capacity = initCapacity;
size = 0;
}else {
System.out.println("线性表的容量不能为负数:" + initCapacity);
}
}
/*
* 获取线性表的容量
*/
public int getCapacity() {
return this.capacity;
}
/*
* 获取线性表中元素的个数
*/
public int getSize() {
return this.size;
}
/*
* 判断线性表是否为空
*/
public boolean isEmpty() {
if(size > 0 ) {
return false;
}else {
return true;
}
}
/*
* 清空线性表
* 1 将中个数组全部删除
* 2 将数组中的元素全部删除
*/
public void clear() {
/*data = null;
capacity = 0;
size = 0 ;*/
if(size > 0 ) {
for(int i = 0 ; i < size; i++) {
data[i] = null;
}
size = 0 ;
}
}
/*
* 获取某一元素
*/
public Object getElement(int index) {
if(index < capacity) {
return data[index];
}else {
System.out.println("你输入的索引超出了范围");
return null;
}
}
/*
* 末位添加一个元素到线性表中
* 如果size = capacity 告诉用户,线性表已满
* 如果size = capacity 实现自动扩容
*/
public void addElement(Object obj) {
validatecp();
data[size++] = obj;
}
/*
* 验证线性表的容量
*/
public void validatecp(){
if(size == capacity) {
capacity = capacity * 2;
Object[] newData = new Object[capacity];
for(int i = 0 ; i < data.length;i++) {
newData[i] = data[i];
}
data = newData;
}
}
/*
* 删除指定的元素
*/
public void deleteEle(int index) {
if(validateIndex(index)) {
for (int i = index; i < size; i++) {
data[i] = data[i + 1];
}
data[size- 1] = null;
size-=1;
}
}
/*
* 判断给出的索引是否有效
*/
public boolean validateIndex(int index) {
if(index < 0 || index > size ) {
System.out.println("索引无效");
return false;
}
return true;
}
/*
* 插入一个元素到指定的位置
*/
public void insertEle(int index,Object ele) {
if(validateIndex(index)) {
validatecp();
for(int i = size; i > index;i--) {
data[i] = data[i - 1];
}
data[index]= ele;
size += 1;
}
}
/*
* 查找某一个元素:如果该元素存在,则返回元素的下标 如果不存在 则返回-1
*/
public int searchElE(Object obj) {
for(int i = 0 ; i < size ; i++) {
if(data[i] == obj && data[i].equals(obj)) {
return i;
}
}
return -1;
}
public void printArrayList() {
for(int i = 0 ; i < size; i++) {
System.out.println(data[i]);
}
}
}
public class Test {
public static void main(String[] args) {
LanqiaoArrayList lal = new LanqiaoArrayList(5);
System.out.println(lal.getCapacity());
System.out.println("-------------------");
lal.addElement(1);
lal.addElement(2);
lal.addElement(3);
lal.addElement(4);
lal.addElement(5);
lal.addElement(6);
lal.printArrayList();
System.out.println("------------------");
lal.insertEle(2, "aaaa");
lal.printArrayList();
System.out.println("------------");
int i = lal.searchElE("aaaaa");
System.out.println(i);
}
}
顺序表的优缺点
优点:
- 存储密度大(结点本身所占存储量/结点结构所占存储量)
- 可以随机存取表中任一元素
缺点:
- 在插入、删除某一元素时,需要移动大量元素
- 浪费存储空间
- 属于静态存储形式,数据元素的个数不能自由扩充