版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/NeptuneClouds/article/details/88372528
定义:
由n(n>=0)个数据特性相同的元素构成的有限序列称为线性表。
特点:
1. 存在唯一的一个被称作“第一个”的数据元素;
2. 存在唯一的一个被称作“最后一个”的数据元素;
3. 除第一个之外,结构中的每个数据元素均只有一个前区;
4. 除最后一个之外,结构中的每个数据元素均只有一个后继;
表示方式:
顺序表示(用一组地址连续的存储单元依次存储线性表的数据元素)
顺序表:通过顺序存储结构存储数据元素
特点:
a、连续的存储单元。
b、预分配空间。
c、随机存取
d、存储密度为1
顺序表
/**
* 数组实现的线性表
*/
public class ArrayList<E> {
Object[] data = null;// 用来保存内容的数组
int current; // 保存当前为第几个元素的指标
int capacity; // 表示数组大小的指标
/**
* 如果初始化时,未声明大小,则默认为10
*/
public ArrayList() {
this(10);
}
/**
* 初始化线性表,并且声明数组大小
*/
public ArrayList(int initalSize) {
if (initalSize < 0) {
throw new RuntimeException("数组大小错误:" + initalSize);
} else {
this.data = new Object[initalSize];
this.current = 0;
capacity = initalSize;
}
}
/**
* 添加前,先确认是否已经满了
*/
public boolean add(E e) {
ensureCapacity(current);// 确认容量
this.data[current] = e;
current++;
return true;
}
/**
* 确认当前容量是否满足需要,如果满足,则执行操作 如果不满足,增加容量
*/
private void ensureCapacity(int cur) {
if (cur == capacity) {
// 如果达到容量极限,增加10的容量,复制当前数组
this.capacity = this.capacity + 10;
Object[] newdata = new Object[capacity];
for (int i = 0; i < cur; i++) {
newdata[i] = this.data[i];
}
this.data = newdata;
}
}
/**
* 得到指定下标的数据
*/
public E get(int index) {
validateIndex(index);
return (E) this.data[index];
}
/**
* 返回当前队列大小
*/
public int size() {
return this.current;
}
/**
* 更改指定下标元素的数据
*/
public boolean set(int index, E e) {
validateIndex(index);
this.data[index] = e;
return true;
}
/**
* 验证当前下标是否合法,如果不合法,抛出运行时异常
*/
private void validateIndex(int index) {
if (index < 0 || index > current) {
throw new RuntimeException("数组index错误:" + index);
}
}
/**
* 在指定下标位置处插入数据
*/
public boolean insert(int index, E e) {
validateIndex(index);
Object[] tem = new Object[capacity];// 用一个临时数组作为备份
//开始备份数组
for (int i = 0; i < current; i++) {
if (i < index) {
tem[i] = this.data[i];
}else if(i==index){
tem[i]=e;
}else if(i>index){
tem[i]=this.data[i-1];
}
}
this.data=tem;
return true;
}
/**
* 删除指定下标出的数据
*/
public boolean delete(int index){
validateIndex(index);
Object[] tem = new Object[capacity];// 用一个临时数组作为备份
//开始备份数组
for (int i = 0; i < current; i++) {
if (i < index) {
tem[i] = this.data[i];
}else if(i==index){
tem[i]=this.data[i+1];
}else if(i>index){
tem[i]=this.data[i+1];
}
}
this.data=tem;
return true;
}
}
链式表示(用一组任意的存储单元存储线性表的数据元素)
链表:有两个域,数据域和指针域。n个结点(Ai(1<=i<=n)的存储映像)链接而成
特点:
a、存储空间不连续。
b、无需预分配空间。
c、顺序存取。
d、存储密度小于1
链表的扩充:
循环链表
双向链表
双向循环链表
单链表
/**
* 链式存储实现的线性表
*/
public class LinkedList<E> {
private Node<E> header = null;// 头结点
int size = 0;// 表示数组大小的指标
public LinkedList() {
this.header = new Node<E>();
}
public boolean add(E e) {
if (size == 0) {
header.e = e;
} else {
// 根据需要添加内容
Node<E> newNode = new Node<E>(e);
// 当前最后一个结点
Node<E> last = getNode(size-1);
// 在最后一个结点后加上新结点
last.addNext(newNode);
}
size++;// 当前大小自增加1
return true;
}
public boolean insert(int index, E e) {
Node<E> newNode = new Node<E>(e);
// 得到第N个结点
Node<E> cNode = getNode(index);
newNode.next = cNode.next;
cNode.next = newNode;
size++;
return true;
}
/**
* 遍历当前链表,取得当前索引对应的元素
*/
private Node<E> getNode(int index) {
// 先判断索引正确性
if (index > size || index < 0) {
throw new RuntimeException("索引值有错:" + index);
}
Node<E> tem = new Node<E>();
tem = header;
int count = 0;
while (count != index) {
tem = tem.next;
count++;
}
return tem;
}
/**
* 根据索引,取得该索引的数据
*/
public E get(int index) {
// 先判断索引正确性
if (index >= size || index < 0) {
throw new RuntimeException("索引值有错:" + index);
}
Node<E> tem = new Node<E>();
tem = header;
int count = 0;
while (count != index) {
tem = tem.next;
count++;
}
E e = tem.e;
return e;
}
public int size() {
return size;
}
/**
* 设置第N个结点的值
*/
public boolean set(int index, E e) {
// 先判断索引正确性
if (index > size || index < 0) {
throw new RuntimeException("索引值有错:" + index);
}
Node<E> newNode = new Node<E>(e);
// 得到第n个结点
Node<E> cNode = getNode(index);
cNode.e = e;
return true;
}
/**
* 用来存放数据的结点型内部类
*/
class Node<e> {
private E e;// 结点中存放的数据
Node<E> next;// 用来指向该结点的下一个结点
Node() { }
Node(E e) {
this.e = e;
}
// 在此结点后加一个结点
void addNext(Node<E> node) {
next = node;
}
}
}